@meistrari/remy-cli 1.25.1-rc.0 → 1.26.0-rc.0
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/README.md +3 -3
- package/dist/remy.js +284 -115
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -70,7 +70,7 @@ The new-session request and conversation composers share path completion and att
|
|
|
70
70
|
|
|
71
71
|
Terminal follow-ups default to **Steer**, targeting the work currently in progress. Press `Ctrl+Enter` to queue a message as **Next**, which waits for current work to finish. Plain `Enter` continues to send as Steer. Failed submissions retain their mode, attachments, settings, and idempotency key when retried with `Ctrl+R`. Remy can replay sessions containing queued-message dispatch, withdrawal, and failure events. Messages withdrawn or failed before reaching Remy show an activity notice; an active submission ends as cancelled or failed instead of waiting for a turn that never started.
|
|
72
72
|
|
|
73
|
-
Use Up/Down to select a session in the dashboard, Left/Right to load the adjacent page, and `Enter` to open it. Remy
|
|
73
|
+
Use Up/Down to select a session in the dashboard, Left/Right to load the adjacent page, and `Enter` to open it. Remy shows the session header and composer immediately after session details load, while retained conversation history loads in the background. You can start drafting immediately; sending is paused until history finishes, and your draft stays intact. New activity then streams as it arrives. Press `s` to fuzzy-search all accessible sessions through the API by author, repository, branch name, pull request title/number, or session number/ID/title; `Enter` applies immediately and keeps the search active; `Esc` clears it. Typing refreshes results after a short pause. Matching ignores case and query whitespace and finds characters in order within a field (for example, `grch` matches `Grace Hopper`); numbers also accept `#`. Search combines with your other filters and stays active across pages. Session rows and compact cards show the repository and session work branch (`Branch pending` when unassigned). Press `f` to filter sessions by lifecycle status, `a` by author, or `r` by repository. These pickers use checkboxes: Up/Down or `j`/`k` moves, `Space` toggles, Right/`l` checks, Left/`h` clears, `G` and `gg` jump to the last and first option, and `Enter` applies every checked value. An empty picker means all values. Press `s` inside a picker to fuzzy-search its options; `Enter` keeps the matching list and `Esc` cancels the search. Press `Esc` outside search to discard staged checkbox changes. Press `b` to filter by a case-insensitive part of a branch name; Enter applies it, an empty value clears it, and Esc discards edits. Repository and branch filters must match the same repository in a session. Filters apply to the complete remote result set and reset pagination to its first page. After the dashboard list or repository-review list has focus, Vim keys work too: `j`/`k` move, `h`/`l` go to the previous/next dashboard page (or clear/mark a repository), `G` goes to the last row, and `gg` goes to the first row. Press `Shift+L` in the dashboard to start a logout confirmation. In any message composer, plain `Enter` and `Shift+Enter` submit; `Option+Enter` on macOS (`Alt+Enter` elsewhere) inserts a newline. `Ctrl+J` also inserts a newline for terminals that do not report the Option/Alt modifier. `Cmd+Left`/`Cmd+Right` move to the start or end of the current line, as do `Home`/`End`, which many macOS terminals send for those keys; `Ctrl+D` deletes the character after the cursor. In the session view, `Ctrl+C` first clears a non-empty draft; press it again with an empty composer to exit. The conversation header keeps the numbered session title on its first line and repository, pull request, work state, elapsed time, connection state, and the agent's current `Harness · Model · Effort` on its second line. The header also keeps the last provider-reported context observation across reconnects, such as `Context 50% left · 62,000 used`; when the provider does not report a context window, it shows only used tokens. This is an observation, not a live occupancy guarantee or billing total.
|
|
74
74
|
|
|
75
75
|
If a connected session loses its activity stream, Remy retries for up to two minutes and resumes from the last received event. After the live stream stays connected for at least 30 seconds, the next disconnect starts a fresh retry window. Connections that drop sooner share the existing window and backoff. While a submitted message is still awaiting its outcome, retries continue beyond that window.
|
|
76
76
|
|
|
@@ -100,7 +100,7 @@ Command and attachment feedback share progress, success, failure, and attention
|
|
|
100
100
|
|
|
101
101
|
Enter `/compact` to admit a durable main-thread context compaction control without sending a human message. Remy reports request admission immediately and shows the eventual completed, no-op, failed, or unknown provider result in retained activity. Compaction waits for a safe point and does not interrupt active work or jump ahead of an earlier Next message. While admission is pending, you can keep editing or open other commands; repeated `/compact` invocations do not send another request.
|
|
102
102
|
|
|
103
|
-
Drag to select visible text in any Remy view; Remy copies it to the local clipboard and emits OSC 52 for terminal or remote-session clipboard support, then clears the selection highlight. Published file artifacts show their filename and muted, full web preview URL; open the URL in a browser to select that artifact in its session. Tela Page rows retain their canonical Page URL. Downloads are explicit through `/files`; artifact bytes are never printed in the terminal.
|
|
103
|
+
Drag to select visible text in any Remy view; Remy copies it to the local clipboard and emits OSC 52 for terminal or remote-session clipboard support, then clears the selection highlight. Published file artifacts show their filename and muted, full web preview URL; open the URL in a browser to select that artifact in its session. Tela Page rows retain their canonical Page URL. Downloads are explicit through `/files`; artifact bytes are never printed in the terminal. Clicking the conversation keeps keyboard focus in the composer. Mouse scrolling and drag-to-select still work. Code blocks and expanded code/output use colored text on a distinct background without copyable gutter bars or added line indentation.
|
|
104
104
|
|
|
105
105
|
| Control | Result |
|
|
106
106
|
| --- | --- |
|
|
@@ -131,7 +131,7 @@ After a session becomes terminal, press `Esc` to return to the dashboard or `n`
|
|
|
131
131
|
|
|
132
132
|
`Shift+L` in the dashboard and `/logout` in a session ask for confirmation; press `y` to sign out or `Esc` to cancel. In the dashboard and repository-review list, Vim navigation is also available: `j`/`k` move, `h`/`l` change dashboard pages (or clear/mark a repository), `G` goes to the last row, and `gg` goes to the first row.
|
|
133
133
|
|
|
134
|
-
Drag to select visible text in any Remy view; Remy copies it to the local clipboard and emits OSC 52 for terminal or remote-session clipboard support, then clears the selection highlight.
|
|
134
|
+
Drag to select visible text in any Remy view; Remy copies it to the local clipboard and emits OSC 52 for terminal or remote-session clipboard support, then clears the selection highlight. Clicking the conversation keeps keyboard focus in the composer. Mouse scrolling and drag-to-select still work. Code blocks and expanded code/output use colored text on a distinct background without copyable gutter bars or added line indentation.
|
|
135
135
|
|
|
136
136
|
</details>
|
|
137
137
|
|
package/dist/remy.js
CHANGED
|
@@ -33544,7 +33544,8 @@ var sessionDetailResponseSchema = exports_external2.object({
|
|
|
33544
33544
|
}).passthrough()),
|
|
33545
33545
|
repositories: exports_external2.array(exports_external2.strictObject({
|
|
33546
33546
|
id: exports_external2.string(),
|
|
33547
|
-
full_name: exports_external2.string()
|
|
33547
|
+
full_name: exports_external2.string(),
|
|
33548
|
+
branch_name: exports_external2.string().nullable().optional()
|
|
33548
33549
|
})),
|
|
33549
33550
|
connections: exports_external2.array(sessionConnectionSchema).max(1),
|
|
33550
33551
|
artifacts: exports_external2.array(sessionArtifactSchema),
|
|
@@ -33594,7 +33595,8 @@ var sessionSummarySchema = exports_external2.object({
|
|
|
33594
33595
|
source: sessionSourceSchema,
|
|
33595
33596
|
repositories: exports_external2.array(exports_external2.strictObject({
|
|
33596
33597
|
id: exports_external2.string(),
|
|
33597
|
-
full_name: exports_external2.string()
|
|
33598
|
+
full_name: exports_external2.string(),
|
|
33599
|
+
branch_name: exports_external2.string().nullable().default(null)
|
|
33598
33600
|
})),
|
|
33599
33601
|
created_by: sessionCreatorSchema,
|
|
33600
33602
|
created_at: exports_external2.string(),
|
|
@@ -33747,6 +33749,9 @@ async function listSessions({
|
|
|
33747
33749
|
after,
|
|
33748
33750
|
statuses,
|
|
33749
33751
|
creatorUserIds,
|
|
33752
|
+
repositoryIds,
|
|
33753
|
+
branchName,
|
|
33754
|
+
search,
|
|
33750
33755
|
signal
|
|
33751
33756
|
}) {
|
|
33752
33757
|
const searchParams = new URLSearchParams;
|
|
@@ -33758,6 +33763,12 @@ async function listSessions({
|
|
|
33758
33763
|
searchParams.append("status", status);
|
|
33759
33764
|
for (const creatorUserId of creatorUserIds ?? [])
|
|
33760
33765
|
searchParams.append("creator_user_id", creatorUserId);
|
|
33766
|
+
for (const repositoryId of repositoryIds ?? [])
|
|
33767
|
+
searchParams.append("repository_id", repositoryId);
|
|
33768
|
+
if (branchName)
|
|
33769
|
+
searchParams.set("branch_name", branchName);
|
|
33770
|
+
if (search)
|
|
33771
|
+
searchParams.set("search", search);
|
|
33761
33772
|
const suffix = searchParams.size > 0 ? `?${searchParams.toString()}` : "";
|
|
33762
33773
|
const response = await client.request(`/v1/sessions${suffix}`, { signal });
|
|
33763
33774
|
const parsed = sessionListResponseSchema.safeParse(await parseJson2(response, "Session list response was not valid JSON."));
|
|
@@ -33777,7 +33788,7 @@ async function listSessions({
|
|
|
33777
33788
|
draft: pullRequest.draft
|
|
33778
33789
|
})),
|
|
33779
33790
|
source: sessionSourceLabel(session.source),
|
|
33780
|
-
repositories: session.repositories.map((repository) => ({ id: repository.id, fullName: repository.full_name })),
|
|
33791
|
+
repositories: session.repositories.map((repository) => ({ id: repository.id, fullName: repository.full_name, branchName: repository.branch_name })),
|
|
33781
33792
|
creator: sessionCreatorLabel(session.created_by),
|
|
33782
33793
|
createdAt: session.created_at,
|
|
33783
33794
|
updatedAt: session.updated_at
|
|
@@ -34592,7 +34603,7 @@ function formatSessionJson({
|
|
|
34592
34603
|
`;
|
|
34593
34604
|
}
|
|
34594
34605
|
// src/version.ts
|
|
34595
|
-
var remyCliVersion = "1.
|
|
34606
|
+
var remyCliVersion = "1.26.0-rc.0";
|
|
34596
34607
|
|
|
34597
34608
|
// src/self-update.ts
|
|
34598
34609
|
import { spawn } from "child_process";
|
|
@@ -35092,6 +35103,7 @@ function createSessionViewState({ detail, activeMessageId }) {
|
|
|
35092
35103
|
title: detail.title ?? null,
|
|
35093
35104
|
aggregateStatus: detail.status,
|
|
35094
35105
|
...detail.agentStatus === undefined ? {} : { agentStatus: detail.agentStatus },
|
|
35106
|
+
historyStatus: "ready",
|
|
35095
35107
|
connectionStatus: "connected",
|
|
35096
35108
|
pullRequest: toSessionPullRequest(detail),
|
|
35097
35109
|
agent: toSessionAgentSettings(detail.agent),
|
|
@@ -36411,19 +36423,22 @@ function createRemoteSessionController(dependencies) {
|
|
|
36411
36423
|
ready = new Promise((resolve) => {
|
|
36412
36424
|
resolveReady = resolve;
|
|
36413
36425
|
});
|
|
36426
|
+
state = { ...createSessionViewState({ detail: input.detail, activeMessageId: dependencies.activeMessageId }), historyStatus: "loading" };
|
|
36414
36427
|
const cache = await readSessionCache(cachePath).catch((error93) => {
|
|
36415
36428
|
handleCacheError(error93);
|
|
36416
36429
|
return null;
|
|
36417
36430
|
});
|
|
36418
36431
|
cachedLastRetainedEventId = input.mode === "live" ? input.lastRetainedEventId ?? cache?.lastRetainedEventId : undefined;
|
|
36419
|
-
|
|
36420
|
-
|
|
36421
|
-
|
|
36422
|
-
});
|
|
36432
|
+
if (stopped)
|
|
36433
|
+
return;
|
|
36434
|
+
state = { ...getState(), activeMessageId: dependencies.activeMessageId ?? cache?.activeMessageId };
|
|
36423
36435
|
if (input.mode === "cold-resume") {
|
|
36424
36436
|
const hydrationGeneration = beginReasoningAttempt();
|
|
36425
36437
|
await hydrateRetainedHistoryFromBeginning(hydrationGeneration);
|
|
36426
36438
|
}
|
|
36439
|
+
if (stopped)
|
|
36440
|
+
return;
|
|
36441
|
+
state = { ...getState(), historyStatus: "ready" };
|
|
36427
36442
|
resolveReady();
|
|
36428
36443
|
publishState();
|
|
36429
36444
|
try {
|
|
@@ -37805,10 +37820,10 @@ import { BoxRenderable as BoxRenderable2, TextRenderable, TextareaRenderable } f
|
|
|
37805
37820
|
import { dim as dim2, fg as fg3, StyledText as StyledText4 } from "@opentui/core";
|
|
37806
37821
|
|
|
37807
37822
|
// src/tui/theme.ts
|
|
37808
|
-
import { bold, dim, fg as fg2, stringToStyledText, StyledText as StyledText3 } from "@opentui/core";
|
|
37823
|
+
import { bg as bg2, bold, dim, fg as fg2, stringToStyledText, StyledText as StyledText3 } from "@opentui/core";
|
|
37809
37824
|
|
|
37810
37825
|
// src/tui/markdown.ts
|
|
37811
|
-
import { fg, StyledText as StyledText2, TextAttributes as TextAttributes2 } from "@opentui/core";
|
|
37826
|
+
import { bg, fg, StyledText as StyledText2, TextAttributes as TextAttributes2 } from "@opentui/core";
|
|
37812
37827
|
|
|
37813
37828
|
// ../../node_modules/.bun/marked@17.0.1/node_modules/marked/lib/marked.esm.js
|
|
37814
37829
|
function L() {
|
|
@@ -39275,7 +39290,7 @@ function renderCodeBlock(token, palette) {
|
|
|
39275
39290
|
`)) {
|
|
39276
39291
|
chunks.push(plain(`
|
|
39277
39292
|
`, { color: palette.body, attributes: 0 }));
|
|
39278
|
-
chunks.push(plain(
|
|
39293
|
+
chunks.push(plain(line, { color: palette.code, background: palette.codeBackground, attributes: 0 }));
|
|
39279
39294
|
}
|
|
39280
39295
|
return chunks;
|
|
39281
39296
|
}
|
|
@@ -39368,6 +39383,8 @@ function trimTrailingNewlines(chunks) {
|
|
|
39368
39383
|
}
|
|
39369
39384
|
function plain(text, style) {
|
|
39370
39385
|
const chunk = fg(style.color)(text);
|
|
39386
|
+
if (style.background)
|
|
39387
|
+
chunk.bg = bg(style.background)(text).bg;
|
|
39371
39388
|
if (style.attributes)
|
|
39372
39389
|
chunk.attributes = style.attributes;
|
|
39373
39390
|
if (style.link)
|
|
@@ -39385,6 +39402,7 @@ var PALETTE = {
|
|
|
39385
39402
|
codeLabel: "#64748B",
|
|
39386
39403
|
codeText: "#93C5FD",
|
|
39387
39404
|
codeBar: "#475569",
|
|
39405
|
+
codeBackground: "#20252E",
|
|
39388
39406
|
reasoning: "#C084FC",
|
|
39389
39407
|
progress: "#60A5FA",
|
|
39390
39408
|
tool: "#22D3EE",
|
|
@@ -39540,7 +39558,7 @@ function renderFencedCodeBody(text) {
|
|
|
39540
39558
|
`)) {
|
|
39541
39559
|
chunks.push(...stringToStyledText(`
|
|
39542
39560
|
`).chunks);
|
|
39543
|
-
chunks.push(
|
|
39561
|
+
chunks.push(bg2(PALETTE.codeBackground)(fg2(PALETTE.codeText)(line)));
|
|
39544
39562
|
}
|
|
39545
39563
|
cursor = start + fence.length;
|
|
39546
39564
|
}
|
|
@@ -39560,7 +39578,8 @@ function renderFormattedMessageBody(text, role2) {
|
|
|
39560
39578
|
muted: PALETTE.dimText,
|
|
39561
39579
|
code: PALETTE.codeText,
|
|
39562
39580
|
codeLabel: PALETTE.codeLabel,
|
|
39563
|
-
codeBar: PALETTE.codeBar
|
|
39581
|
+
codeBar: PALETTE.codeBar,
|
|
39582
|
+
codeBackground: PALETTE.codeBackground
|
|
39564
39583
|
});
|
|
39565
39584
|
if (formattedMessages.size >= FORMATTED_MESSAGE_CACHE_LIMIT)
|
|
39566
39585
|
formattedMessages.delete(formattedMessages.keys().next().value);
|
|
@@ -39568,14 +39587,12 @@ function renderFormattedMessageBody(text, role2) {
|
|
|
39568
39587
|
return formatted;
|
|
39569
39588
|
}
|
|
39570
39589
|
function renderCodeSnippet({ text, language = "code", indent = "" }) {
|
|
39571
|
-
const gutter = `${indent}\u2502 `;
|
|
39572
39590
|
return new StyledText3([
|
|
39573
39591
|
...indent ? [dim(fg2(PALETTE.dimText)(indent))] : [],
|
|
39574
39592
|
dim(fg2(PALETTE.codeLabel)(language)),
|
|
39575
39593
|
fg2(PALETTE.codeText)(`
|
|
39576
|
-
|
|
39577
|
-
|
|
39578
|
-
${gutter}`)}`)
|
|
39594
|
+
`),
|
|
39595
|
+
bg2(PALETTE.codeBackground)(fg2(PALETTE.codeText)(text))
|
|
39579
39596
|
]);
|
|
39580
39597
|
}
|
|
39581
39598
|
function formatTime(occurredAt) {
|
|
@@ -39761,12 +39778,12 @@ function renderKeyHints({ hints, width }) {
|
|
|
39761
39778
|
}
|
|
39762
39779
|
|
|
39763
39780
|
// src/tui/selection.ts
|
|
39764
|
-
import { bg, bold as bold2, fg as fg5 } from "@opentui/core";
|
|
39781
|
+
import { bg as bg3, bold as bold2, fg as fg5 } from "@opentui/core";
|
|
39765
39782
|
function selectionLabel({ text, checked }) {
|
|
39766
39783
|
return checked ? bold2(fg5(PALETTE.humanAccent)(text)) : fg5(PALETTE.dimText)(text);
|
|
39767
39784
|
}
|
|
39768
39785
|
function highlightSelection({ chunks, cursor }) {
|
|
39769
|
-
return cursor ? chunks.map((chunk) =>
|
|
39786
|
+
return cursor ? chunks.map((chunk) => bg3(PALETTE.selectionBg)(chunk)) : chunks;
|
|
39770
39787
|
}
|
|
39771
39788
|
|
|
39772
39789
|
// src/tui/renderer.ts
|
|
@@ -40659,7 +40676,9 @@ var lifecycleStatusOptions = [
|
|
|
40659
40676
|
];
|
|
40660
40677
|
async function createDashboardTui({
|
|
40661
40678
|
initialPage,
|
|
40662
|
-
initialFilters = { statuses: [], creators: [] },
|
|
40679
|
+
initialFilters = { statuses: [], creators: [], repositories: [], branchName: "" },
|
|
40680
|
+
repositories: initialRepositories = [],
|
|
40681
|
+
loadRepositories,
|
|
40663
40682
|
authors: initialAuthors = [],
|
|
40664
40683
|
loadAuthors,
|
|
40665
40684
|
loadPage,
|
|
@@ -40670,23 +40689,27 @@ async function createDashboardTui({
|
|
|
40670
40689
|
let keyHandler;
|
|
40671
40690
|
let resizeHandler;
|
|
40672
40691
|
let refreshTimer;
|
|
40692
|
+
let searchTimer;
|
|
40673
40693
|
let contentScrollHandler;
|
|
40674
40694
|
let rendererDestroyed2 = false;
|
|
40675
40695
|
const loadPageAbortController = new AbortController;
|
|
40676
40696
|
try {
|
|
40677
40697
|
let stopPageRefresh = function() {
|
|
40698
|
+
clearTimeout(searchTimer);
|
|
40678
40699
|
if (refreshTimer !== undefined) {
|
|
40679
40700
|
clearInterval(refreshTimer);
|
|
40680
40701
|
refreshTimer = undefined;
|
|
40681
40702
|
}
|
|
40682
40703
|
loadPageAbortController.abort();
|
|
40704
|
+
}, currentOptionState = function() {
|
|
40705
|
+
return filterMode?.kind === "creator" || filterMode?.kind === "repository" ? optionStates[filterMode.kind] : undefined;
|
|
40683
40706
|
}, render = function() {
|
|
40684
40707
|
const contentWidth = Math.max(1, renderer.width - TUI_LAYOUT.dashboardGutter * 2);
|
|
40685
|
-
const sessions =
|
|
40708
|
+
const sessions = page.sessions.map((session) => prioritizeSessionMatches(session, filters, sessionSearchQuery));
|
|
40686
40709
|
const rowsBelow = rowsBelowVisibleWindow({ sessionCount: sessions.length, selectedIndex, height: renderer.height });
|
|
40687
40710
|
const isNarrow = renderer.width < TUI_LAYOUT.dashboardCardBreakpoint;
|
|
40688
40711
|
const selectedSession = filterMode ? undefined : sessions[selectedIndex];
|
|
40689
|
-
const sessionRows = filterMode ? formatFilterMenu({ mode: filterMode, authors, width: contentWidth }) : sessions.length === 0 ? stringToStyledText2(sessionSearchQuery ? "No sessions match the search." : hasActiveFilters(filters) ? "No sessions match the active filters." : "No remote sessions yet.") : isNarrow ? formatSessionCard({
|
|
40712
|
+
const sessionRows = filterMode ? formatFilterMenu({ mode: filterMode, authors, repositories, width: contentWidth }) : sessions.length === 0 ? stringToStyledText2(sessionSearchQuery ? "No sessions match the search." : hasActiveFilters(filters) ? "No sessions match the active filters." : "No remote sessions yet.") : isNarrow ? formatSessionCard({
|
|
40690
40713
|
session: selectedSession,
|
|
40691
40714
|
selectedIndex,
|
|
40692
40715
|
sessionCount: sessions.length,
|
|
@@ -40736,7 +40759,7 @@ async function createDashboardTui({
|
|
|
40736
40759
|
else if (activeSearchComposer === "session")
|
|
40737
40760
|
sessionSearchComposer.render();
|
|
40738
40761
|
separator.content = activeSearchComposer ? "" : renderComposerDivider({ width: contentWidth });
|
|
40739
|
-
footer.content = filterMode ? dashboardFilterFooter({ mode: filterMode, loadingPage,
|
|
40762
|
+
footer.content = filterMode ? dashboardFilterFooter({ mode: filterMode, loadingPage, loadingOptions: currentOptionState()?.loading ?? false, pageError, optionError: currentOptionState()?.error, width: contentWidth }) : dashboardFooter({ loadingPage, pageError, rowsBelow, logoutConfirmationOpen, sessionSearchOpen, width: contentWidth });
|
|
40740
40763
|
renderer.requestRender();
|
|
40741
40764
|
}, finish = function(value) {
|
|
40742
40765
|
if (settled)
|
|
@@ -40751,7 +40774,7 @@ async function createDashboardTui({
|
|
|
40751
40774
|
stopPageRefresh();
|
|
40752
40775
|
rejectDraft(error93);
|
|
40753
40776
|
}, moveSelectionTo = function(index) {
|
|
40754
|
-
const sessions =
|
|
40777
|
+
const sessions = page.sessions;
|
|
40755
40778
|
if (sessions.length === 0)
|
|
40756
40779
|
return;
|
|
40757
40780
|
selectedIndex = Math.max(0, Math.min(index, sessions.length - 1));
|
|
@@ -40759,6 +40782,10 @@ async function createDashboardTui({
|
|
|
40759
40782
|
}, applyFilterSearch = function() {
|
|
40760
40783
|
if (!filterMode?.searching)
|
|
40761
40784
|
return;
|
|
40785
|
+
if (filterMode.kind === "branch") {
|
|
40786
|
+
applyFilters({ ...filters, statuses: filterMode.statuses, creators: filterMode.creators, repositories: filterMode.repositories, branchName: filterMode.query.trim() });
|
|
40787
|
+
return;
|
|
40788
|
+
}
|
|
40762
40789
|
filterMode = { ...filterMode, searching: false, selectedIndex: 0 };
|
|
40763
40790
|
filterSearchComposer.textarea.setText("");
|
|
40764
40791
|
render();
|
|
@@ -40777,6 +40804,7 @@ async function createDashboardTui({
|
|
|
40777
40804
|
return;
|
|
40778
40805
|
sessionSearchOpen = false;
|
|
40779
40806
|
selectedIndex = 0;
|
|
40807
|
+
loadSessionSearch();
|
|
40780
40808
|
render();
|
|
40781
40809
|
}, cancelSessionSearch = function() {
|
|
40782
40810
|
if (!sessionSearchOpen)
|
|
@@ -40785,6 +40813,7 @@ async function createDashboardTui({
|
|
|
40785
40813
|
sessionSearchQuery = "";
|
|
40786
40814
|
selectedIndex = 0;
|
|
40787
40815
|
sessionSearchComposer.textarea.setText("");
|
|
40816
|
+
loadSessionSearch();
|
|
40788
40817
|
render();
|
|
40789
40818
|
}, handleSessionKey = function(key) {
|
|
40790
40819
|
if (logoutConfirmationOpen) {
|
|
@@ -40805,22 +40834,21 @@ async function createDashboardTui({
|
|
|
40805
40834
|
return;
|
|
40806
40835
|
}
|
|
40807
40836
|
if (filterMode) {
|
|
40808
|
-
const options = visibleDashboardFilterOptions({ mode: filterMode, authors });
|
|
40837
|
+
const options = visibleDashboardFilterOptions({ mode: filterMode, authors, repositories });
|
|
40809
40838
|
if (key.name === "escape") {
|
|
40810
40839
|
key.preventDefault();
|
|
40811
|
-
if (filterMode.searching) {
|
|
40840
|
+
if (filterMode.searching && filterMode.kind !== "branch") {
|
|
40812
40841
|
cancelFilterSearch();
|
|
40813
40842
|
return;
|
|
40814
40843
|
}
|
|
40815
40844
|
filterMode = undefined;
|
|
40816
40845
|
pageError = undefined;
|
|
40817
|
-
authorError = undefined;
|
|
40818
40846
|
render();
|
|
40819
40847
|
return;
|
|
40820
40848
|
}
|
|
40821
40849
|
if (filterMode.searching)
|
|
40822
40850
|
return;
|
|
40823
|
-
if (
|
|
40851
|
+
if (currentOptionState()?.loading) {
|
|
40824
40852
|
key.preventDefault();
|
|
40825
40853
|
return;
|
|
40826
40854
|
}
|
|
@@ -40857,7 +40885,7 @@ async function createDashboardTui({
|
|
|
40857
40885
|
if (!option)
|
|
40858
40886
|
return;
|
|
40859
40887
|
const selected = key.name === "space" ? !isDashboardFilterOptionSelected({ mode: filterMode, option }) : key.name === "right" || key.name === "l";
|
|
40860
|
-
filterMode = updateDashboardFilterSelection({ mode: filterMode, option, selected, authors });
|
|
40888
|
+
filterMode = updateDashboardFilterSelection({ mode: filterMode, option, selected, authors, repositories });
|
|
40861
40889
|
render();
|
|
40862
40890
|
return;
|
|
40863
40891
|
}
|
|
@@ -40870,7 +40898,7 @@ async function createDashboardTui({
|
|
|
40870
40898
|
}
|
|
40871
40899
|
if (key.name === "return" || key.name === "enter") {
|
|
40872
40900
|
key.preventDefault();
|
|
40873
|
-
const nextFilters = { statuses: [...filterMode.statuses], creators: [...filterMode.creators] };
|
|
40901
|
+
const nextFilters = { ...filters, statuses: [...filterMode.statuses], creators: [...filterMode.creators], repositories: [...filterMode.repositories], branchName: filterMode.branchName };
|
|
40874
40902
|
applyFilters(nextFilters);
|
|
40875
40903
|
}
|
|
40876
40904
|
return;
|
|
@@ -40903,7 +40931,7 @@ async function createDashboardTui({
|
|
|
40903
40931
|
if (listFocused && (key.name === "G" || key.name === "g" && key.shift)) {
|
|
40904
40932
|
key.preventDefault();
|
|
40905
40933
|
awaitingVimGoToTop = false;
|
|
40906
|
-
moveSelectionTo(
|
|
40934
|
+
moveSelectionTo(page.sessions.length - 1);
|
|
40907
40935
|
return;
|
|
40908
40936
|
}
|
|
40909
40937
|
if (listFocused && key.name === "g") {
|
|
@@ -40928,7 +40956,9 @@ async function createDashboardTui({
|
|
|
40928
40956
|
awaitingVimGoToTop = false;
|
|
40929
40957
|
if (key.name === "return" || key.name === "enter") {
|
|
40930
40958
|
key.preventDefault();
|
|
40931
|
-
|
|
40959
|
+
if (loadingPage || sessionSearchQuery.trim() !== (filters.search ?? ""))
|
|
40960
|
+
return;
|
|
40961
|
+
const session = page.sessions[selectedIndex];
|
|
40932
40962
|
if (session)
|
|
40933
40963
|
finish({ kind: "session", sessionId: session.id });
|
|
40934
40964
|
return;
|
|
@@ -40943,13 +40973,27 @@ async function createDashboardTui({
|
|
|
40943
40973
|
openSessionSearch();
|
|
40944
40974
|
return;
|
|
40945
40975
|
}
|
|
40976
|
+
if (["f", "a", "r", "b"].includes(key.name) && (loadingPage || sessionSearchQuery.trim() !== (filters.search ?? "")))
|
|
40977
|
+
return;
|
|
40946
40978
|
if (key.name === "f") {
|
|
40947
40979
|
key.preventDefault();
|
|
40948
|
-
authorError = undefined;
|
|
40949
40980
|
filterMode = createFilterMode({ kind: "status", filters });
|
|
40950
40981
|
render();
|
|
40951
40982
|
return;
|
|
40952
40983
|
}
|
|
40984
|
+
if (key.name === "r" || key.name === "b") {
|
|
40985
|
+
key.preventDefault();
|
|
40986
|
+
filterMode = createFilterMode({ kind: key.name === "r" ? "repository" : "branch", filters });
|
|
40987
|
+
if (filterMode.kind === "branch") {
|
|
40988
|
+
filterMode.searching = true;
|
|
40989
|
+
filterMode.query = filters.branchName;
|
|
40990
|
+
filterSearchComposer.textarea.setText(filters.branchName);
|
|
40991
|
+
}
|
|
40992
|
+
render();
|
|
40993
|
+
if (key.name === "r")
|
|
40994
|
+
loadRepositoryOptions();
|
|
40995
|
+
return;
|
|
40996
|
+
}
|
|
40953
40997
|
if (key.name === "a") {
|
|
40954
40998
|
key.preventDefault();
|
|
40955
40999
|
openAuthorFilter();
|
|
@@ -40992,17 +41036,22 @@ async function createDashboardTui({
|
|
|
40992
41036
|
let selectedIndex = 0;
|
|
40993
41037
|
let loadingPage = false;
|
|
40994
41038
|
let pageRequestInFlight = false;
|
|
41039
|
+
let pageRequestVersion = 0;
|
|
40995
41040
|
let pageError;
|
|
40996
|
-
|
|
41041
|
+
const optionStates = {
|
|
41042
|
+
creator: { loading: false, error: undefined },
|
|
41043
|
+
repository: { loading: false, error: undefined }
|
|
41044
|
+
};
|
|
41045
|
+
let repositories = initialRepositories;
|
|
41046
|
+
let repositoriesLoaded = loadRepositories === undefined || initialRepositories.length > 0;
|
|
40997
41047
|
let authors = initialAuthors;
|
|
40998
41048
|
let authorsLoaded = loadAuthors === undefined || initialAuthors.length > 0;
|
|
40999
|
-
let loadingAuthors = false;
|
|
41000
41049
|
let awaitingVimGoToTop = false;
|
|
41001
41050
|
let logoutConfirmationOpen = false;
|
|
41002
41051
|
let filters = initialFilters;
|
|
41003
41052
|
let filterMode;
|
|
41004
41053
|
let sessionSearchOpen = false;
|
|
41005
|
-
let sessionSearchQuery = "";
|
|
41054
|
+
let sessionSearchQuery = initialFilters.search ?? "";
|
|
41006
41055
|
root.onMouseDown = (event) => {
|
|
41007
41056
|
if (filterMode?.searching || sessionSearchOpen)
|
|
41008
41057
|
return;
|
|
@@ -41042,7 +41091,7 @@ async function createDashboardTui({
|
|
|
41042
41091
|
renderer,
|
|
41043
41092
|
parent: filterSearchRegion,
|
|
41044
41093
|
tag: "Search",
|
|
41045
|
-
placeholder: "Search
|
|
41094
|
+
placeholder: "Search sessions, authors, repositories, branches, or PRs\u2026",
|
|
41046
41095
|
screenPaddingX: 2,
|
|
41047
41096
|
onSubmit: () => applySessionSearch(),
|
|
41048
41097
|
onContentChange: () => {
|
|
@@ -41050,104 +41099,151 @@ async function createDashboardTui({
|
|
|
41050
41099
|
return;
|
|
41051
41100
|
sessionSearchQuery = sessionSearchComposer.textarea.plainText;
|
|
41052
41101
|
selectedIndex = 0;
|
|
41102
|
+
pageRequestVersion += 1;
|
|
41103
|
+
loadingPage = true;
|
|
41104
|
+
clearTimeout(searchTimer);
|
|
41105
|
+
searchTimer = setTimeout(() => {
|
|
41106
|
+
searchTimer = undefined;
|
|
41107
|
+
loadSessionSearch();
|
|
41108
|
+
}, 200);
|
|
41053
41109
|
render();
|
|
41054
41110
|
}
|
|
41055
41111
|
});
|
|
41056
41112
|
async function loadAdjacentPage(direction) {
|
|
41057
|
-
if (pageRequestInFlight)
|
|
41113
|
+
if (pageRequestInFlight || loadingPage || sessionSearchQuery.trim() !== (filters.search ?? ""))
|
|
41058
41114
|
return;
|
|
41059
41115
|
const canLoad = direction === "next" ? page.hasMore : page.canGoPrevious;
|
|
41060
41116
|
if (!canLoad)
|
|
41061
41117
|
return;
|
|
41118
|
+
const requestVersion = ++pageRequestVersion;
|
|
41062
41119
|
pageRequestInFlight = true;
|
|
41063
41120
|
loadingPage = true;
|
|
41064
41121
|
pageError = undefined;
|
|
41065
41122
|
render();
|
|
41066
41123
|
try {
|
|
41067
41124
|
const loadedPage = await loadPage({ target: direction, signal: loadPageAbortController.signal });
|
|
41068
|
-
if (destroyed || settled)
|
|
41125
|
+
if (destroyed || settled || requestVersion !== pageRequestVersion)
|
|
41069
41126
|
return;
|
|
41070
41127
|
page = loadedPage;
|
|
41071
41128
|
pageIndex = Math.max(1, pageIndex + (direction === "next" ? 1 : -1));
|
|
41072
|
-
const sessions =
|
|
41129
|
+
const sessions = page.sessions;
|
|
41073
41130
|
selectedIndex = direction === "next" ? 0 : Math.max(0, sessions.length - 1);
|
|
41074
41131
|
} catch (error93) {
|
|
41075
|
-
if (!destroyed && !settled)
|
|
41132
|
+
if (!destroyed && !settled && requestVersion === pageRequestVersion)
|
|
41076
41133
|
pageError = error93 instanceof Error ? error93.message : String(error93);
|
|
41077
41134
|
} finally {
|
|
41078
|
-
|
|
41079
|
-
|
|
41080
|
-
|
|
41081
|
-
|
|
41135
|
+
if (requestVersion === pageRequestVersion) {
|
|
41136
|
+
pageRequestInFlight = false;
|
|
41137
|
+
loadingPage = false;
|
|
41138
|
+
if (!destroyed && !settled)
|
|
41139
|
+
render();
|
|
41140
|
+
}
|
|
41082
41141
|
}
|
|
41083
41142
|
}
|
|
41084
41143
|
async function refreshCurrentPage() {
|
|
41085
|
-
if (pageRequestInFlight || destroyed || settled)
|
|
41144
|
+
if (pageRequestInFlight || loadingPage || destroyed || settled || sessionSearchQuery.trim() !== (filters.search ?? ""))
|
|
41086
41145
|
return;
|
|
41146
|
+
const requestVersion = ++pageRequestVersion;
|
|
41087
41147
|
pageRequestInFlight = true;
|
|
41088
41148
|
try {
|
|
41089
41149
|
const refreshedPage = await loadPage({ target: "current", signal: loadPageAbortController.signal });
|
|
41090
|
-
if (destroyed || settled)
|
|
41150
|
+
if (destroyed || settled || requestVersion !== pageRequestVersion)
|
|
41091
41151
|
return;
|
|
41092
|
-
const selectedSessionId =
|
|
41152
|
+
const selectedSessionId = page.sessions[selectedIndex]?.id;
|
|
41093
41153
|
page = refreshedPage;
|
|
41094
|
-
const refreshedSelectedIndex = selectedSessionId ?
|
|
41154
|
+
const refreshedSelectedIndex = selectedSessionId ? page.sessions.findIndex((session) => session.id === selectedSessionId) : -1;
|
|
41095
41155
|
selectedIndex = refreshedSelectedIndex >= 0 ? refreshedSelectedIndex : Math.max(0, Math.min(selectedIndex, page.sessions.length - 1));
|
|
41096
41156
|
pageError = undefined;
|
|
41097
41157
|
render();
|
|
41098
41158
|
} catch (error93) {
|
|
41099
|
-
if (!destroyed && !settled) {
|
|
41159
|
+
if (!destroyed && !settled && requestVersion === pageRequestVersion) {
|
|
41100
41160
|
pageError = error93 instanceof Error ? error93.message : String(error93);
|
|
41101
41161
|
render();
|
|
41102
41162
|
}
|
|
41103
41163
|
} finally {
|
|
41104
|
-
|
|
41164
|
+
if (requestVersion === pageRequestVersion)
|
|
41165
|
+
pageRequestInFlight = false;
|
|
41105
41166
|
}
|
|
41106
41167
|
}
|
|
41107
41168
|
async function applyFilters(nextFilters) {
|
|
41108
|
-
|
|
41109
|
-
|
|
41169
|
+
const appliedFilterMode = filterMode;
|
|
41170
|
+
const requestVersion = ++pageRequestVersion;
|
|
41171
|
+
pageRequestInFlight = true;
|
|
41110
41172
|
loadingPage = true;
|
|
41111
41173
|
pageError = undefined;
|
|
41112
|
-
authorError = undefined;
|
|
41113
41174
|
render();
|
|
41114
41175
|
try {
|
|
41115
|
-
|
|
41176
|
+
const loadedPage = await loadPage({ filters: nextFilters, signal: loadPageAbortController.signal });
|
|
41177
|
+
if (destroyed || settled || requestVersion !== pageRequestVersion)
|
|
41178
|
+
return;
|
|
41179
|
+
page = loadedPage;
|
|
41116
41180
|
filters = nextFilters;
|
|
41117
41181
|
pageIndex = 1;
|
|
41118
41182
|
selectedIndex = 0;
|
|
41119
|
-
filterMode
|
|
41183
|
+
if (filterMode === appliedFilterMode)
|
|
41184
|
+
filterMode = undefined;
|
|
41120
41185
|
} catch (error93) {
|
|
41121
|
-
|
|
41186
|
+
if (!destroyed && !settled && requestVersion === pageRequestVersion)
|
|
41187
|
+
pageError = error93 instanceof Error ? error93.message : String(error93);
|
|
41122
41188
|
} finally {
|
|
41123
|
-
|
|
41124
|
-
|
|
41189
|
+
if (requestVersion === pageRequestVersion) {
|
|
41190
|
+
pageRequestInFlight = false;
|
|
41191
|
+
loadingPage = false;
|
|
41192
|
+
if (!destroyed && !settled)
|
|
41193
|
+
render();
|
|
41194
|
+
}
|
|
41195
|
+
}
|
|
41196
|
+
}
|
|
41197
|
+
async function loadRepositoryOptions() {
|
|
41198
|
+
if (repositoriesLoaded || optionStates.repository.loading || !loadRepositories)
|
|
41199
|
+
return;
|
|
41200
|
+
optionStates.repository.loading = true;
|
|
41201
|
+
optionStates.repository.error = undefined;
|
|
41202
|
+
render();
|
|
41203
|
+
try {
|
|
41204
|
+
const loaded = await loadRepositories();
|
|
41205
|
+
if (destroyed || settled)
|
|
41206
|
+
return;
|
|
41207
|
+
repositories = loaded;
|
|
41208
|
+
repositoriesLoaded = true;
|
|
41209
|
+
} catch (error93) {
|
|
41210
|
+
if (!destroyed && !settled)
|
|
41211
|
+
optionStates.repository.error = error93 instanceof Error ? error93.message : String(error93);
|
|
41212
|
+
} finally {
|
|
41213
|
+
optionStates.repository.loading = false;
|
|
41214
|
+
if (!destroyed && !settled)
|
|
41215
|
+
render();
|
|
41125
41216
|
}
|
|
41126
41217
|
}
|
|
41127
41218
|
async function openAuthorFilter() {
|
|
41128
41219
|
filterMode = createFilterMode({ kind: "creator", filters });
|
|
41129
|
-
|
|
41220
|
+
optionStates.creator.error = undefined;
|
|
41130
41221
|
render();
|
|
41131
|
-
if (authorsLoaded ||
|
|
41222
|
+
if (authorsLoaded || optionStates.creator.loading || !loadAuthors)
|
|
41132
41223
|
return;
|
|
41133
|
-
|
|
41224
|
+
optionStates.creator.loading = true;
|
|
41134
41225
|
render();
|
|
41135
41226
|
try {
|
|
41136
|
-
|
|
41227
|
+
const loaded = await loadAuthors();
|
|
41228
|
+
if (destroyed || settled)
|
|
41229
|
+
return;
|
|
41230
|
+
authors = loaded;
|
|
41137
41231
|
authorsLoaded = true;
|
|
41138
41232
|
if (filterMode?.kind === "creator") {
|
|
41139
41233
|
const firstSelectedIndex = authors.findIndex((author) => filterMode?.creators.some((creator) => creator.id === author.id));
|
|
41140
41234
|
filterMode = { ...filterMode, selectedIndex: Math.max(0, firstSelectedIndex) };
|
|
41141
41235
|
}
|
|
41142
41236
|
} catch (error93) {
|
|
41143
|
-
|
|
41237
|
+
if (!destroyed && !settled)
|
|
41238
|
+
optionStates.creator.error = error93 instanceof Error ? error93.message : String(error93);
|
|
41144
41239
|
} finally {
|
|
41145
|
-
|
|
41146
|
-
|
|
41240
|
+
optionStates.creator.loading = false;
|
|
41241
|
+
if (!destroyed && !settled)
|
|
41242
|
+
render();
|
|
41147
41243
|
}
|
|
41148
41244
|
}
|
|
41149
41245
|
async function moveSelection(direction) {
|
|
41150
|
-
const sessions =
|
|
41246
|
+
const sessions = page.sessions;
|
|
41151
41247
|
if (loadingPage || sessions.length === 0)
|
|
41152
41248
|
return;
|
|
41153
41249
|
const isBoundary = direction === "next" ? selectedIndex === sessions.length - 1 : selectedIndex === 0;
|
|
@@ -41158,6 +41254,12 @@ async function createDashboardTui({
|
|
|
41158
41254
|
}
|
|
41159
41255
|
await loadAdjacentPage(direction);
|
|
41160
41256
|
}
|
|
41257
|
+
async function loadSessionSearch() {
|
|
41258
|
+
clearTimeout(searchTimer);
|
|
41259
|
+
searchTimer = undefined;
|
|
41260
|
+
const search = sessionSearchQuery.trim();
|
|
41261
|
+
await applyFilters({ ...filters, search: search || undefined });
|
|
41262
|
+
}
|
|
41161
41263
|
inputHandler = (sequence) => {
|
|
41162
41264
|
if (sequence === "\x03") {
|
|
41163
41265
|
finish({ kind: "interrupt" });
|
|
@@ -41236,7 +41338,8 @@ function formatSessionRow({ session, selected, width }) {
|
|
|
41236
41338
|
const title = truncateText(session.title ?? "Untitled session", Math.max(8, Math.min(40, Math.floor(width * 0.24))));
|
|
41237
41339
|
const attribution = `${session.creator} (${session.source})`;
|
|
41238
41340
|
const metadataWidth = Math.max(0, width - Bun.stringWidth(prefix + title + activity.label) - 4);
|
|
41239
|
-
const
|
|
41341
|
+
const work = session.repositories.length > 0 ? `${sessionRepositoryBranches(session, Math.max(0, Math.floor(metadataWidth * 0.6)))} \xB7 ` : "";
|
|
41342
|
+
const metadata = truncateText(`${work}${attribution} \xB7 ${outcome} \xB7 ${updated}`, metadataWidth);
|
|
41240
41343
|
const line = [
|
|
41241
41344
|
fg7(PALETTE.dimText)(prefix),
|
|
41242
41345
|
fg7(PALETTE.bodyText)(title),
|
|
@@ -41264,14 +41367,18 @@ function createFilterMode({ kind, filters }) {
|
|
|
41264
41367
|
selectedIndex: 0,
|
|
41265
41368
|
statuses: [...filters.statuses],
|
|
41266
41369
|
creators: [...filters.creators],
|
|
41370
|
+
repositories: [...filters.repositories],
|
|
41371
|
+
branchName: filters.branchName,
|
|
41267
41372
|
query: "",
|
|
41268
41373
|
searching: false
|
|
41269
41374
|
};
|
|
41270
41375
|
}
|
|
41271
|
-
function formatFilterMenu({ mode, authors, width }) {
|
|
41272
|
-
|
|
41273
|
-
|
|
41274
|
-
const
|
|
41376
|
+
function formatFilterMenu({ mode, authors, repositories, width }) {
|
|
41377
|
+
if (mode.kind === "branch")
|
|
41378
|
+
return stringToStyledText2("Filter by branch \xB7 contains text \xB7 empty shows all");
|
|
41379
|
+
const options = visibleDashboardFilterOptions({ mode, authors, repositories });
|
|
41380
|
+
const selectedCount = mode.kind === "status" ? mode.statuses.length : mode.kind === "repository" ? mode.repositories.length : mode.creators.length;
|
|
41381
|
+
const heading = `${mode.kind === "status" ? "Filter by status" : mode.kind === "repository" ? "Filter by repository" : "Filter by author"} \xB7 ${selectedCount} selected \xB7 empty shows all`;
|
|
41275
41382
|
const rows = options.map((option, index) => {
|
|
41276
41383
|
const active = isDashboardFilterOptionSelected({ mode, option });
|
|
41277
41384
|
const label = `${active ? "[x]" : "[ ]"} ${truncateText(option.label, Math.max(1, width - 4))}`;
|
|
@@ -41286,16 +41393,16 @@ function formatFilterMenu({ mode, authors, width }) {
|
|
|
41286
41393
|
], `
|
|
41287
41394
|
`);
|
|
41288
41395
|
}
|
|
41289
|
-
function dashboardFilterOptions({ kind, authors }) {
|
|
41290
|
-
return kind === "status" ? lifecycleStatusOptions.map((option) => ({ kind: "status", id: option.value, label: option.label })) : authors.map((author) => ({ kind: "creator", id: author.id, label: author.name }));
|
|
41396
|
+
function dashboardFilterOptions({ kind, authors, repositories }) {
|
|
41397
|
+
return kind === "status" ? lifecycleStatusOptions.map((option) => ({ kind: "status", id: option.value, label: option.label })) : kind === "repository" ? repositories.map((repository) => ({ kind: "repository", id: repository.id, label: repository.fullName })) : authors.map((author) => ({ kind: "creator", id: author.id, label: author.name }));
|
|
41291
41398
|
}
|
|
41292
|
-
function visibleDashboardFilterOptions({ mode, authors }) {
|
|
41293
|
-
return dashboardFilterOptions({ kind: mode.kind, authors }).filter((option) => fuzzyMatches(option.label, mode.query));
|
|
41399
|
+
function visibleDashboardFilterOptions({ mode, authors, repositories }) {
|
|
41400
|
+
return dashboardFilterOptions({ kind: mode.kind, authors, repositories }).filter((option) => fuzzyMatches(option.label, mode.query));
|
|
41294
41401
|
}
|
|
41295
41402
|
function isDashboardFilterOptionSelected({ mode, option }) {
|
|
41296
|
-
return option.kind === "status" ? mode.statuses.includes(option.id) : mode.creators.some((creator) => creator.id === option.id);
|
|
41403
|
+
return option.kind === "status" ? mode.statuses.includes(option.id) : option.kind === "repository" ? mode.repositories.some((repository) => repository.id === option.id) : mode.creators.some((creator) => creator.id === option.id);
|
|
41297
41404
|
}
|
|
41298
|
-
function updateDashboardFilterSelection({ mode, option, selected, authors }) {
|
|
41405
|
+
function updateDashboardFilterSelection({ mode, option, selected, authors, repositories }) {
|
|
41299
41406
|
if (option.kind === "status") {
|
|
41300
41407
|
const selectedStatuses = new Set(mode.statuses);
|
|
41301
41408
|
if (selected)
|
|
@@ -41307,6 +41414,14 @@ function updateDashboardFilterSelection({ mode, option, selected, authors }) {
|
|
|
41307
41414
|
statuses: lifecycleStatusOptions.map((entry2) => entry2.value).filter((status) => selectedStatuses.has(status))
|
|
41308
41415
|
};
|
|
41309
41416
|
}
|
|
41417
|
+
if (option.kind === "repository") {
|
|
41418
|
+
const ids = new Set(mode.repositories.map((repository) => repository.id));
|
|
41419
|
+
if (selected)
|
|
41420
|
+
ids.add(option.id);
|
|
41421
|
+
else
|
|
41422
|
+
ids.delete(option.id);
|
|
41423
|
+
return { ...mode, repositories: repositories.filter((repository) => ids.has(repository.id)).map(({ id, fullName }) => ({ id, fullName })) };
|
|
41424
|
+
}
|
|
41310
41425
|
const selectedCreatorIds = new Set(mode.creators.map((creator) => creator.id));
|
|
41311
41426
|
if (selected)
|
|
41312
41427
|
selectedCreatorIds.add(option.id);
|
|
@@ -41334,7 +41449,7 @@ function formatSessionPreview({ session, width }) {
|
|
|
41334
41449
|
fg7(PALETTE.dimText)(" \xB7 "),
|
|
41335
41450
|
bold3(fg7(activity.color)(activity.label))
|
|
41336
41451
|
],
|
|
41337
|
-
[fg7(PALETTE.dimText)(truncateText(`Work: ${sessionWork(session)}`, width))],
|
|
41452
|
+
[fg7(PALETTE.dimText)(truncateText(`Work: ${sessionWork(session, width)}`, width))],
|
|
41338
41453
|
[fg7(PALETTE.bodyText)(truncateText(`Outcome: ${sessionOutcome(session)}`, width))],
|
|
41339
41454
|
[fg7(PALETTE.dimText)(truncateText(`Created by: ${session.creator} \xB7 Updated ${formatUpdatedAt(session.updatedAt ?? session.createdAt)}`, width))]
|
|
41340
41455
|
], `
|
|
@@ -41345,7 +41460,7 @@ function formatSessionCard({ session, selectedIndex, sessionCount, width }) {
|
|
|
41345
41460
|
const lines = [
|
|
41346
41461
|
`Session #${session.sessionNumber} \xB7 ${selectedIndex + 1} of ${sessionCount}`,
|
|
41347
41462
|
truncateText(session.title ?? "Untitled session", width),
|
|
41348
|
-
truncateText(`Work: ${sessionWork(session)}`, width),
|
|
41463
|
+
truncateText(`Work: ${sessionWork(session, width)}`, width),
|
|
41349
41464
|
`Now: ${activity.label}`,
|
|
41350
41465
|
truncateText(`Outcome: ${sessionOutcome(session)}`, width),
|
|
41351
41466
|
truncateText(`Created by: ${session.creator} \xB7 Updated ${formatUpdatedAt(session.updatedAt ?? session.createdAt)}`, width)
|
|
@@ -41378,9 +41493,33 @@ function sessionActivityPresentation(session) {
|
|
|
41378
41493
|
return { ...agent, label: "Ready" };
|
|
41379
41494
|
return agent;
|
|
41380
41495
|
}
|
|
41381
|
-
function
|
|
41382
|
-
const
|
|
41383
|
-
|
|
41496
|
+
function prioritizeSessionMatches(session, filters, query) {
|
|
41497
|
+
const filteredRepositories = session.repositories.filter((repository2) => (filters.repositories.length === 0 || filters.repositories.some((selected) => selected.id === repository2.id)) && (!filters.branchName || repository2.branchName?.toLowerCase().includes(filters.branchName.toLowerCase())));
|
|
41498
|
+
const repository = filteredRepositories.find((repository2) => fuzzyMatches(repository2.fullName, query) || fuzzyMatches(repository2.branchName ?? "", query)) ?? filteredRepositories[0];
|
|
41499
|
+
const pullRequest = session.pullRequests.find((pullRequest2) => matchesPullRequestSearch(pullRequest2, query));
|
|
41500
|
+
return {
|
|
41501
|
+
...session,
|
|
41502
|
+
repositories: repository ? [repository, ...session.repositories.filter((item) => item !== repository)] : session.repositories,
|
|
41503
|
+
pullRequests: pullRequest ? [pullRequest, ...session.pullRequests.filter((item) => item !== pullRequest)] : session.pullRequests
|
|
41504
|
+
};
|
|
41505
|
+
}
|
|
41506
|
+
function matchesPullRequestSearch(pullRequest, query) {
|
|
41507
|
+
return fuzzyMatches(`#${pullRequest.number}`, query) || fuzzyMatches(pullRequest.title, query);
|
|
41508
|
+
}
|
|
41509
|
+
function sessionRepositoryBranches(session, width) {
|
|
41510
|
+
const repository = session.repositories[0];
|
|
41511
|
+
if (!repository)
|
|
41512
|
+
return truncateText("No repository selected", width);
|
|
41513
|
+
const more = session.repositories.length > 1 ? ` +${session.repositories.length - 1}` : "";
|
|
41514
|
+
const available = Math.max(0, width - Bun.stringWidth(more) - 3);
|
|
41515
|
+
const name = truncateText(repository.fullName, Math.floor(available / 2));
|
|
41516
|
+
const branch = truncateText(repository.branchName ?? "Branch pending", Math.max(0, available - Bun.stringWidth(name)));
|
|
41517
|
+
return `${name} \xB7 ${branch}${more}`;
|
|
41518
|
+
}
|
|
41519
|
+
function sessionWork(session, width) {
|
|
41520
|
+
const source = truncateText(session.source, Math.floor(width / 4));
|
|
41521
|
+
const repositories = sessionRepositoryBranches(session, Math.max(0, width - Bun.stringWidth(source) - 9));
|
|
41522
|
+
return `${repositories} \xB7 ${source}`;
|
|
41384
41523
|
}
|
|
41385
41524
|
function sessionOutcome(session) {
|
|
41386
41525
|
const first = session.pullRequests[0];
|
|
@@ -41403,14 +41542,8 @@ function formatUpdatedAt(value) {
|
|
|
41403
41542
|
return `${Math.floor(seconds / (60 * 60))}h ago`;
|
|
41404
41543
|
return new Date(milliseconds).toLocaleDateString(undefined, { month: "short", day: "numeric" });
|
|
41405
41544
|
}
|
|
41406
|
-
function matchesSessionSearch({ session, query }) {
|
|
41407
|
-
return fuzzyMatches(session.id, query) || fuzzyMatches(session.title ?? "", query) || fuzzyMatches(String(session.sessionNumber), query);
|
|
41408
|
-
}
|
|
41409
|
-
function visibleDashboardSessions({ sessions, query }) {
|
|
41410
|
-
return sessions.filter((session) => matchesSessionSearch({ session, query }));
|
|
41411
|
-
}
|
|
41412
41545
|
function dashboardStatusBand({ page, pageIndex, filters, sessionSearchQuery }) {
|
|
41413
|
-
const openCount =
|
|
41546
|
+
const openCount = page.sessions.filter((session) => session.status === "open").length;
|
|
41414
41547
|
const paging = [`page ${pageIndex}`];
|
|
41415
41548
|
if (page.canGoPrevious)
|
|
41416
41549
|
paging.push("\u2190 prev");
|
|
@@ -41419,12 +41552,14 @@ function dashboardStatusBand({ page, pageIndex, filters, sessionSearchQuery }) {
|
|
|
41419
41552
|
const activeFilters = [
|
|
41420
41553
|
filters.statuses.length > 0 ? `status: ${filters.statuses.map(sessionStatusLabel).join(", ")}` : undefined,
|
|
41421
41554
|
filters.creators.length > 0 ? `author: ${filters.creators.map((creator) => creator.name).join(", ")}` : undefined,
|
|
41555
|
+
filters.repositories.length > 0 ? `repo: ${filters.repositories.map((repository) => repository.fullName).join(", ")}` : undefined,
|
|
41556
|
+
filters.branchName ? `branch: ${filters.branchName}` : undefined,
|
|
41422
41557
|
sessionSearchQuery ? `search: ${sessionSearchQuery}` : undefined
|
|
41423
41558
|
].filter((value) => value !== undefined);
|
|
41424
41559
|
return `remy \xB7 sessions \xB7 ${openCount} open${activeFilters.length > 0 ? ` \xB7 ${activeFilters.join(" \xB7 ")}` : ""} \xB7 ${paging.join(" \xB7 ")}`;
|
|
41425
41560
|
}
|
|
41426
41561
|
function hasActiveFilters(filters) {
|
|
41427
|
-
return filters.statuses.length > 0 || filters.creators.length > 0;
|
|
41562
|
+
return filters.statuses.length > 0 || filters.creators.length > 0 || filters.repositories.length > 0 || filters.branchName.length > 0;
|
|
41428
41563
|
}
|
|
41429
41564
|
function dashboardFooter({ loadingPage, pageError, rowsBelow, logoutConfirmationOpen, sessionSearchOpen, width }) {
|
|
41430
41565
|
if (logoutConfirmationOpen)
|
|
@@ -41440,19 +41575,24 @@ function dashboardFooter({ loadingPage, pageError, rowsBelow, logoutConfirmation
|
|
|
41440
41575
|
parts.push(`\u2193 ${rowsBelow} more below`);
|
|
41441
41576
|
return joinStyled([
|
|
41442
41577
|
...parts.length > 0 ? [[fg7(pageError ? PALETTE.failure : PALETTE.dimText)(parts.join(" \xB7 "))]] : [],
|
|
41443
|
-
renderKeyHints({ hints: [{ key: "\u2191\u2193", action: "move" }, { key: "\u23CE", action: "open" }, { key: "s", action: "search" }, { key: "f", action: "status" }, { key: "a", action: "author" }, { key: "n", action: "new session" }, { key: "\u21E7l", action: "log out" }, { key: "q", action: "quit" }], width })
|
|
41578
|
+
renderKeyHints({ hints: [{ key: "\u2191\u2193", action: "move" }, { key: "\u23CE", action: "open" }, { key: "s", action: "search" }, { key: "f", action: "status" }, { key: "a", action: "author" }, { key: "r", action: "repository" }, { key: "b", action: "branch" }, { key: "n", action: "new session" }, { key: "\u21E7l", action: "log out" }, { key: "q", action: "quit" }], width })
|
|
41444
41579
|
], `
|
|
41445
41580
|
`);
|
|
41446
41581
|
}
|
|
41447
|
-
function dashboardFilterFooter({ mode, loadingPage,
|
|
41448
|
-
if (
|
|
41449
|
-
return joinStyled([[fg7(PALETTE.progress)("Loading
|
|
41582
|
+
function dashboardFilterFooter({ mode, loadingPage, loadingOptions, pageError, optionError, width }) {
|
|
41583
|
+
if (loadingOptions)
|
|
41584
|
+
return joinStyled([[fg7(PALETTE.progress)("Loading filter options\u2026")], renderKeyHints({ hints: [{ key: "Esc", action: "cancel" }], width })], " \xB7 ");
|
|
41450
41585
|
if (loadingPage)
|
|
41451
41586
|
return stringToStyledText2("Applying filter\u2026");
|
|
41452
|
-
if (mode.searching)
|
|
41453
|
-
return
|
|
41587
|
+
if (mode.searching) {
|
|
41588
|
+
return joinStyled([
|
|
41589
|
+
...pageError ? [[fg7(PALETTE.failure)(`Could not apply filter: ${pageError}`)]] : [],
|
|
41590
|
+
renderKeyHints({ hints: [{ key: "type", action: "to filter" }, { key: "\u23CE", action: mode.kind === "branch" ? "apply branch" : "apply search" }, { key: "Esc", action: "cancel" }], width })
|
|
41591
|
+
], `
|
|
41592
|
+
`);
|
|
41593
|
+
}
|
|
41454
41594
|
return joinStyled([
|
|
41455
|
-
...
|
|
41595
|
+
...optionError ? [[fg7(PALETTE.failure)(`Could not load filter options: ${optionError}`)]] : [],
|
|
41456
41596
|
...pageError ? [[fg7(PALETTE.failure)(`Could not apply filter: ${pageError}`)]] : [],
|
|
41457
41597
|
renderKeyHints({ hints: [{ key: "\u2191\u2193/jk", action: "move" }, { key: "space", action: "toggle" }, { key: "\u2190\u2192/hl", action: "mark" }, { key: "s", action: "search" }, { key: "\u23CE", action: "apply" }, { key: "Esc", action: "cancel" }], width })
|
|
41458
41598
|
], `
|
|
@@ -41463,7 +41603,7 @@ async function createDefaultRenderer() {
|
|
|
41463
41603
|
}
|
|
41464
41604
|
|
|
41465
41605
|
// src/tui/new-session-wizard.ts
|
|
41466
|
-
import { bg as
|
|
41606
|
+
import { bg as bg4, bold as bold4, CliRenderEvents as CliRenderEvents4, dim as dim6, fg as fg11, StyledText as StyledText10, stringToStyledText as stringToStyledText3, TextRenderable as TextRenderable4 } from "@opentui/core";
|
|
41467
41607
|
|
|
41468
41608
|
// src/tui/attachment-presentation.ts
|
|
41469
41609
|
import { dim as dim4, fg as fg9, StyledText as StyledText8 } from "@opentui/core";
|
|
@@ -42941,7 +43081,7 @@ function renderStepIndicator({ step, hasInstallationChoice, hasBranchChoice = fa
|
|
|
42941
43081
|
function renderSelectableRow({ label, isCursor }) {
|
|
42942
43082
|
const line = `${isCursor ? "> " : " "}${label}`;
|
|
42943
43083
|
const styled = fg11(PALETTE.bodyText)(line);
|
|
42944
|
-
return [isCursor ?
|
|
43084
|
+
return [isCursor ? bg4(PALETTE.selectionBg)(styled) : styled];
|
|
42945
43085
|
}
|
|
42946
43086
|
function renderRepositoryRow({ repository, isCursor, isChecked, source }) {
|
|
42947
43087
|
const marker = isChecked ? "[x]" : "[ ]";
|
|
@@ -42965,7 +43105,7 @@ async function createDefaultRenderer2() {
|
|
|
42965
43105
|
}
|
|
42966
43106
|
|
|
42967
43107
|
// src/tui/session-view.ts
|
|
42968
|
-
import { CliRenderEvents as CliRenderEvents5, bg as
|
|
43108
|
+
import { CliRenderEvents as CliRenderEvents5, bg as bg5, bold as bold5, dim as dim7, fg as fg12, link as link2, StyledText as StyledText11, stringToStyledText as stringToStyledText5, TextRenderable as TextRenderable5 } from "@opentui/core";
|
|
42969
43109
|
|
|
42970
43110
|
// src/tui/session-mcps-view.ts
|
|
42971
43111
|
import { stringToStyledText as stringToStyledText4 } from "@opentui/core";
|
|
@@ -43344,7 +43484,7 @@ async function createSessionTui({
|
|
|
43344
43484
|
`), joinStyled(liveContent, `
|
|
43345
43485
|
|
|
43346
43486
|
`)], ""));
|
|
43347
|
-
composer.placeholder = lifecycleRequestState.kind === "pending" ? `${lifecycleOperationPresentParticiple(lifecycleRequestState.operation)} the session \u2014 messages are paused.` : renderer.height <= 10 ? "Message Remy\u2026 \xB7 Enter sends" : idleComposerPlaceholder;
|
|
43487
|
+
composer.placeholder = latestState.historyStatus === "loading" ? "Draft a message\u2026 \xB7 sending waits for history" : lifecycleRequestState.kind === "pending" ? `${lifecycleOperationPresentParticiple(lifecycleRequestState.operation)} the session \u2014 messages are paused.` : renderer.height <= 10 ? "Message Remy\u2026 \xB7 Enter sends" : idleComposerPlaceholder;
|
|
43348
43488
|
resizeComposer(composer);
|
|
43349
43489
|
if (latestState.aggregateStatus === "open")
|
|
43350
43490
|
composerLayout.render();
|
|
@@ -43353,6 +43493,7 @@ async function createSessionTui({
|
|
|
43353
43493
|
const commandMenu = renderSlashCommandMenu({ commands: slashCompletions, selectedIndex: slashCompletionIndex, width: renderer.width - 2, maxRows: completionMenuRows(renderer.height) });
|
|
43354
43494
|
const agentSettingsMenu = agentSettingsPicker && latestState.aggregateStatus === "open" ? renderAgentSettingsPicker({ picker: agentSettingsPicker, width: renderer.width - 2, maxRows: completionMenuRows(renderer.height) }) : undefined;
|
|
43355
43495
|
const composerStatus = [
|
|
43496
|
+
latestState.historyStatus === "loading" ? renderFeedback({ kind: "progress", message: "Loading conversation\u2026 You can draft now; sending is paused." }) : undefined,
|
|
43356
43497
|
composerDraft.workspaceContexts?.length ? renderFeedback({ kind: "info", message: `${composerDraft.workspaceContexts.length} workspace context(s) \xB7 /context to review/remove` }) : undefined,
|
|
43357
43498
|
attachmentFeedback ? renderAttachmentFeedback(attachmentFeedback) : undefined,
|
|
43358
43499
|
composerFeedback ? renderFeedback(composerFeedback) : undefined,
|
|
@@ -44016,6 +44157,12 @@ ${segment.excerpt}`).join(`
|
|
|
44016
44157
|
render();
|
|
44017
44158
|
}
|
|
44018
44159
|
}
|
|
44160
|
+
transcriptScrollBox.onMouseDown = (event) => {
|
|
44161
|
+
if (latestState.aggregateStatus === "open" && event.button === 0) {
|
|
44162
|
+
event.preventDefault();
|
|
44163
|
+
composer.focus();
|
|
44164
|
+
}
|
|
44165
|
+
};
|
|
44019
44166
|
for (const text of [transcript, liveTranscript]) {
|
|
44020
44167
|
let pressedLink;
|
|
44021
44168
|
text.onMouseDown = (event) => {
|
|
@@ -44069,6 +44216,10 @@ ${segment.excerpt}`).join(`
|
|
|
44069
44216
|
}
|
|
44070
44217
|
if (!ownsAttachmentPreparation(preparationOwner))
|
|
44071
44218
|
return;
|
|
44219
|
+
if (latestState.historyStatus === "loading") {
|
|
44220
|
+
invalidateAttachmentPreparation();
|
|
44221
|
+
return;
|
|
44222
|
+
}
|
|
44072
44223
|
if (lifecycleRequestState.kind === "pending") {
|
|
44073
44224
|
composerFeedback = { kind: "progress", message: `${lifecycleOperationPresentParticiple(lifecycleRequestState.operation)} the session \u2014 messages are paused.` };
|
|
44074
44225
|
render();
|
|
@@ -44535,8 +44686,8 @@ function renderTerminalSessionBand({ aggregateStatus, width }) {
|
|
|
44535
44686
|
const status = sessionStatusLabel(aggregateStatus).toLowerCase();
|
|
44536
44687
|
return joinStyled([
|
|
44537
44688
|
new StyledText11([
|
|
44538
|
-
|
|
44539
|
-
|
|
44689
|
+
bg5(PALETTE.selectionBg)(bold5(fg12(PALETTE.systemAccent)(` Session ${status} `))),
|
|
44690
|
+
bg5(PALETTE.selectionBg)(fg12(PALETTE.bodyText)("\u2014 this conversation is closed. "))
|
|
44540
44691
|
]),
|
|
44541
44692
|
renderKeyHints({ hints: [{ key: "esc", action: "return to dashboard" }, { key: "n", action: "new session" }, { key: "m", action: "MCPs" }, { key: "ctrl+f", action: "files" }, { key: "ctrl+l", action: "links" }], width })
|
|
44542
44693
|
], `
|
|
@@ -45245,7 +45396,7 @@ function isPng(bytes) {
|
|
|
45245
45396
|
}
|
|
45246
45397
|
|
|
45247
45398
|
// src/tui/remy-splash.ts
|
|
45248
|
-
import { bold as bold6, BoxRenderable as BoxRenderable5, fg as fg13, NativeImage, StyledText as StyledText12, TextRenderable as TextRenderable6, bg as
|
|
45399
|
+
import { bold as bold6, BoxRenderable as BoxRenderable5, fg as fg13, NativeImage, StyledText as StyledText12, TextRenderable as TextRenderable6, bg as bg6 } from "@opentui/core";
|
|
45249
45400
|
|
|
45250
45401
|
// src/tui/remy-mark.ts
|
|
45251
45402
|
var remyPixelFieldSource = new URL("../assets/remy-pixel-field.png", import.meta.url);
|
|
@@ -45519,7 +45670,7 @@ function renderMark(field, frame, rows = markRows) {
|
|
|
45519
45670
|
const flush = () => {
|
|
45520
45671
|
if (runLength === 0)
|
|
45521
45672
|
return;
|
|
45522
|
-
chunks.push(fg13(grey(runTop))(
|
|
45673
|
+
chunks.push(fg13(grey(runTop))(bg6(grey(runBottom))(upperHalfBlock.repeat(runLength))));
|
|
45523
45674
|
runLength = 0;
|
|
45524
45675
|
};
|
|
45525
45676
|
for (let column = 0;column < columns; column++) {
|
|
@@ -46091,7 +46242,7 @@ async function dashboard({
|
|
|
46091
46242
|
const openDashboardTui = dependencies.openDashboardTui ?? createDashboardTui;
|
|
46092
46243
|
const pages = [initialSessions];
|
|
46093
46244
|
let pageIndex = 0;
|
|
46094
|
-
let filters = { statuses: [], creators: [] };
|
|
46245
|
+
let filters = { statuses: [], creators: [], repositories: [], branchName: "" };
|
|
46095
46246
|
let authors;
|
|
46096
46247
|
let activeDashboardGeneration = 0;
|
|
46097
46248
|
function holdTransitionScreen() {
|
|
@@ -46100,8 +46251,9 @@ async function dashboard({
|
|
|
46100
46251
|
function createDashboardPageLoader({ generation }) {
|
|
46101
46252
|
const loadingPages = new Map;
|
|
46102
46253
|
let pageLoadTail = Promise.resolve();
|
|
46254
|
+
let filterRequestNumber = 0;
|
|
46103
46255
|
return async (input) => {
|
|
46104
|
-
const requestKey = "filters" in input ? `filters:${
|
|
46256
|
+
const requestKey = "filters" in input ? `filters:${++filterRequestNumber}` : input.target;
|
|
46105
46257
|
const matchingPageLoad = loadingPages.get(requestKey);
|
|
46106
46258
|
if (matchingPageLoad)
|
|
46107
46259
|
return await matchingPageLoad;
|
|
@@ -46116,6 +46268,9 @@ async function dashboard({
|
|
|
46116
46268
|
limit: 20,
|
|
46117
46269
|
...nextFilters.statuses.length > 0 ? { statuses: nextFilters.statuses } : {},
|
|
46118
46270
|
...nextFilters.creators.length > 0 ? { creatorUserIds: nextFilters.creators.map((creator) => creator.id) } : {},
|
|
46271
|
+
...nextFilters.repositories.length > 0 ? { repositoryIds: nextFilters.repositories.map((repository) => repository.id) } : {},
|
|
46272
|
+
...nextFilters.branchName ? { branchName: nextFilters.branchName } : {},
|
|
46273
|
+
...nextFilters.search ? { search: nextFilters.search } : {},
|
|
46119
46274
|
signal: input.signal
|
|
46120
46275
|
}));
|
|
46121
46276
|
if (generation !== activeDashboardGeneration)
|
|
@@ -46134,6 +46289,9 @@ async function dashboard({
|
|
|
46134
46289
|
after,
|
|
46135
46290
|
...filters.statuses.length > 0 ? { statuses: filters.statuses } : {},
|
|
46136
46291
|
...filters.creators.length > 0 ? { creatorUserIds: filters.creators.map((creator) => creator.id) } : {},
|
|
46292
|
+
...filters.repositories.length > 0 ? { repositoryIds: filters.repositories.map((repository) => repository.id) } : {},
|
|
46293
|
+
...filters.branchName ? { branchName: filters.branchName } : {},
|
|
46294
|
+
...filters.search ? { search: filters.search } : {},
|
|
46137
46295
|
signal
|
|
46138
46296
|
}));
|
|
46139
46297
|
if (generation !== activeDashboardGeneration)
|
|
@@ -46154,6 +46312,9 @@ async function dashboard({
|
|
|
46154
46312
|
after: current.nextCursor,
|
|
46155
46313
|
...filters.statuses.length > 0 ? { statuses: filters.statuses } : {},
|
|
46156
46314
|
...filters.creators.length > 0 ? { creatorUserIds: filters.creators.map((creator) => creator.id) } : {},
|
|
46315
|
+
...filters.repositories.length > 0 ? { repositoryIds: filters.repositories.map((repository) => repository.id) } : {},
|
|
46316
|
+
...filters.branchName ? { branchName: filters.branchName } : {},
|
|
46317
|
+
...filters.search ? { search: filters.search } : {},
|
|
46157
46318
|
signal
|
|
46158
46319
|
}));
|
|
46159
46320
|
if (generation !== activeDashboardGeneration)
|
|
@@ -46193,6 +46354,9 @@ async function dashboard({
|
|
|
46193
46354
|
limit: 20,
|
|
46194
46355
|
...filters.statuses.length > 0 ? { statuses: filters.statuses } : {},
|
|
46195
46356
|
...filters.creators.length > 0 ? { creatorUserIds: filters.creators.map((creator) => creator.id) } : {},
|
|
46357
|
+
...filters.repositories.length > 0 ? { repositoryIds: filters.repositories.map((repository) => repository.id) } : {},
|
|
46358
|
+
...filters.branchName ? { branchName: filters.branchName } : {},
|
|
46359
|
+
...filters.search ? { search: filters.search } : {},
|
|
46196
46360
|
signal: dependencies.abortSignal
|
|
46197
46361
|
})));
|
|
46198
46362
|
pageIndex = 0;
|
|
@@ -46203,6 +46367,7 @@ async function dashboard({
|
|
|
46203
46367
|
const action = await renderRemyView({
|
|
46204
46368
|
open: async () => await openDashboardTui({
|
|
46205
46369
|
initialPage: pages[0],
|
|
46370
|
+
loadRepositories: async () => await repositories,
|
|
46206
46371
|
initialFilters: filters,
|
|
46207
46372
|
loadAuthors: loadDashboardAuthors,
|
|
46208
46373
|
loadPage: loadDashboardPage
|
|
@@ -46731,6 +46896,9 @@ async function runAttachedSession({
|
|
|
46731
46896
|
const aborted3 = interactive ? new Promise((_resolve, reject) => {
|
|
46732
46897
|
rejectAborted = reject;
|
|
46733
46898
|
}) : undefined;
|
|
46899
|
+
aborted3?.catch(() => {
|
|
46900
|
+
return;
|
|
46901
|
+
});
|
|
46734
46902
|
const abortHandler = () => {
|
|
46735
46903
|
stop();
|
|
46736
46904
|
rejectAborted(dependencies.abortSignal?.reason instanceof Error ? dependencies.abortSignal.reason : new Error("interrupted"));
|
|
@@ -46747,11 +46915,12 @@ async function runAttachedSession({
|
|
|
46747
46915
|
});
|
|
46748
46916
|
}
|
|
46749
46917
|
const startPromise = controller.start(start);
|
|
46750
|
-
await Promise
|
|
46751
|
-
|
|
46752
|
-
|
|
46753
|
-
|
|
46754
|
-
|
|
46918
|
+
const controllerFailed = startPromise.then(async () => await new Promise(() => {}));
|
|
46919
|
+
controllerFailed.catch(() => {
|
|
46920
|
+
return;
|
|
46921
|
+
});
|
|
46922
|
+
if (!interactive)
|
|
46923
|
+
await Promise.race([controller.waitUntilReady(), startPromise, ...aborted3 ? [aborted3] : []]);
|
|
46755
46924
|
if (interactive) {
|
|
46756
46925
|
if (dependencies.abortSignal?.aborted)
|
|
46757
46926
|
throw dependencies.abortSignal.reason ?? new Error("interrupted");
|
|
@@ -46824,7 +46993,7 @@ async function runAttachedSession({
|
|
|
46824
46993
|
savePastedImage: async (input) => await writePastedImage({ ...input, temporaryDirectory: tmpdir2() }),
|
|
46825
46994
|
attachPromptPaths: async (input) => await uploadPromptPaths({ operations, ...input })
|
|
46826
46995
|
}),
|
|
46827
|
-
waitForAction: async (tui) => await Promise.race([tui.waitForAction(), aborted3])
|
|
46996
|
+
waitForAction: async (tui) => await Promise.race([tui.waitForAction(), aborted3, controllerFailed])
|
|
46828
46997
|
});
|
|
46829
46998
|
if (!action)
|
|
46830
46999
|
throw dependencies.abortSignal?.reason ?? new Error("interrupted");
|
|
@@ -46911,7 +47080,7 @@ async function runAttachedSession({
|
|
|
46911
47080
|
view.invalidate(event);
|
|
46912
47081
|
}
|
|
46913
47082
|
mountedView = view;
|
|
46914
|
-
return await Promise.race([view.waitForAction(), aborted3]);
|
|
47083
|
+
return await Promise.race([view.waitForAction(), aborted3, controllerFailed]);
|
|
46915
47084
|
}
|
|
46916
47085
|
});
|
|
46917
47086
|
if (!result2 || result2.kind === "interrupt")
|