@meistrari/remy-cli 1.4.3 → 1.6.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 +6 -4
- package/dist/remy.js +269 -29
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,11 +32,11 @@ On first use, Remy opens browser-based device authorization, validates your Codi
|
|
|
32
32
|
|
|
33
33
|
## Your everyday workflow
|
|
34
34
|
|
|
35
|
-
The dashboard is the starting point for all interactive work.
|
|
35
|
+
The dashboard is the starting point for all interactive work. It refreshes the visible session page every 10 seconds, so new sessions and status changes appear while you keep it open. If an update fails, Remy keeps showing the last successful list and retries on the next interval.
|
|
36
36
|
|
|
37
37
|
### Start work
|
|
38
38
|
|
|
39
|
-
Press `n` in the dashboard. The new-session flow asks what you want done, selects a GitHub installation when needed, suggests repositories based on your request, and lets you review those suggestions. Before creating the session, choose the agent model and reasoning effort. Remy then opens the session and streams its activity.
|
|
39
|
+
Press `n` in the dashboard. The new-session flow asks what you want done, selects a GitHub installation when needed, suggests repositories based on your request, and lets you review those suggestions. Before creating the session, choose the agent model and reasoning effort. Reasoning starts at `high` by default. Remy then opens the session and streams its activity.
|
|
40
40
|
|
|
41
41
|
Use `Tab` while writing the request to complete a local file path. Remy attaches selected paths when you confirm the request. On macOS, `Ctrl+V` adds a PNG from the system clipboard to the request; Remy attaches it on confirmation. Remy uploads files before creating the session.
|
|
42
42
|
|
|
@@ -44,6 +44,8 @@ Use `Tab` while writing the request to complete a local file path. Remy attaches
|
|
|
44
44
|
|
|
45
45
|
Use Up/Down to select a session in the dashboard, Left/Right to load the adjacent page, and `Enter` to open it. 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 a session, type a follow-up and press `Enter` to send it.
|
|
46
46
|
|
|
47
|
+
When Remy creates a plan, the session shows its checklist in the timeline and keeps `Plan <done>/<total>` with the current item pinned above the composer. Updates change the same checklist instead of producing repeated rows, and an unfinished plan remains visible after reconnecting or between turns. The collapsed timeline shows up to five plan items; press `Ctrl+O` for the complete checklist and activity detail.
|
|
48
|
+
|
|
47
49
|
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. When the conversation has focus, press `Tab` to return to the composer.
|
|
48
50
|
|
|
49
51
|
| Control | Result |
|
|
@@ -56,7 +58,7 @@ Drag to select visible text in any Remy view; Remy copies it to the local clipbo
|
|
|
56
58
|
| `/logout` | Sign out of Remy after confirmation. |
|
|
57
59
|
| `/help` | Show session controls. |
|
|
58
60
|
| `/exit` | Leave Remy. |
|
|
59
|
-
| `Ctrl+O` | Expand or collapse activity details. |
|
|
61
|
+
| `Ctrl+O` | Expand or collapse full plan and activity details. |
|
|
60
62
|
|
|
61
63
|
After a session becomes terminal, press `Esc` to return to the dashboard or `n` to start new work. From the dashboard, press `q` to quit; in an open session, `q` is ordinary composer text. `Shift+L` in the dashboard and `/logout` in a session ask for confirmation; press `y` to sign out or `Esc` to cancel. `Ctrl+C` exits Remy from the dashboard, wizard, or session view.
|
|
62
64
|
|
|
@@ -70,7 +72,7 @@ The interactive dashboard is the recommended path. Use these commands when a scr
|
|
|
70
72
|
remy new --repository owner/repository "Add a health check endpoint"
|
|
71
73
|
```
|
|
72
74
|
|
|
73
|
-
Repeat `--repository` to select more repositories from the same GitHub installation. If you do not select a repository, supply `--installation <github-installation-id>`. Repeat `--attach <path>` to upload files. `remy new` creates the session from the prompt and flags, then opens it when the terminal is interactive.
|
|
75
|
+
Repeat `--repository` to select more repositories from the same GitHub installation. If you do not select a repository, supply `--installation <github-installation-id>`. Repeat `--attach <path>` to upload files. Direct creation uses `high` reasoning unless `--reasoning-effort` overrides it. `remy new` creates the session from the prompt and flags, then opens it when the terminal is interactive.
|
|
74
76
|
|
|
75
77
|
### Open a known session
|
|
76
78
|
|
package/dist/remy.js
CHANGED
|
@@ -32222,6 +32222,37 @@ var agentWorkObservationSchema = zod_default2.discriminatedUnion("kind", [
|
|
|
32222
32222
|
var agentWorkStateSchema = zod_default2.object({
|
|
32223
32223
|
items: zod_default2.array(agentWorkItemSchema)
|
|
32224
32224
|
}).strict();
|
|
32225
|
+
function applyAgentWorkObservations(state, observations) {
|
|
32226
|
+
let items = state.items.map((item) => ({ ...item }));
|
|
32227
|
+
for (const observation of observations) {
|
|
32228
|
+
switch (observation.kind) {
|
|
32229
|
+
case "snapshot":
|
|
32230
|
+
items = observation.items.map((item) => ({ ...item }));
|
|
32231
|
+
break;
|
|
32232
|
+
case "item_observed": {
|
|
32233
|
+
const existingIndex = items.findIndex((item) => item.id === observation.item.id);
|
|
32234
|
+
if (existingIndex === -1)
|
|
32235
|
+
items = [...items, { ...observation.item }];
|
|
32236
|
+
else
|
|
32237
|
+
items = items.map((item, index) => index === existingIndex ? { ...observation.item } : item);
|
|
32238
|
+
break;
|
|
32239
|
+
}
|
|
32240
|
+
case "item_renamed":
|
|
32241
|
+
items = items.map((item) => item.id === observation.itemId ? { ...item, title: observation.title } : item);
|
|
32242
|
+
break;
|
|
32243
|
+
case "item_status_changed":
|
|
32244
|
+
items = items.map((item) => item.id === observation.itemId ? { ...item, status: observation.status } : item);
|
|
32245
|
+
break;
|
|
32246
|
+
case "item_removed":
|
|
32247
|
+
items = items.filter((item) => item.id !== observation.itemId);
|
|
32248
|
+
break;
|
|
32249
|
+
default: {
|
|
32250
|
+
const exhaustiveObservation = observation;
|
|
32251
|
+
}
|
|
32252
|
+
}
|
|
32253
|
+
}
|
|
32254
|
+
return { items };
|
|
32255
|
+
}
|
|
32225
32256
|
|
|
32226
32257
|
// ../../packages/agents-protocol/src/agent-event.ts
|
|
32227
32258
|
var agentErrorSchema = zod_default2.object({
|
|
@@ -33643,6 +33674,20 @@ function formatSessionJson({
|
|
|
33643
33674
|
`;
|
|
33644
33675
|
}
|
|
33645
33676
|
|
|
33677
|
+
// src/session-agent-options.ts
|
|
33678
|
+
function newSessionModelLabel(model) {
|
|
33679
|
+
return codexModelPresentation[model].label;
|
|
33680
|
+
}
|
|
33681
|
+
function newSessionReasoningEffortLabel(effort) {
|
|
33682
|
+
return agentReasoningEffortPresentation[effort].label;
|
|
33683
|
+
}
|
|
33684
|
+
var newSessionModels = codexModelIds;
|
|
33685
|
+
var newSessionReasoningEfforts = selectableAgentReasoningEfforts;
|
|
33686
|
+
var defaultNewSessionAgent = {
|
|
33687
|
+
model: codexModelIds[0],
|
|
33688
|
+
reasoningEffort: "high"
|
|
33689
|
+
};
|
|
33690
|
+
|
|
33646
33691
|
// src/sessions/session-controller.ts
|
|
33647
33692
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
33648
33693
|
import { mkdir as mkdir4, readFile as readFile4, rename as rename3, writeFile as writeFile2 } from "fs/promises";
|
|
@@ -33852,6 +33897,8 @@ function createSessionViewState({ detail, activeMessageId }) {
|
|
|
33852
33897
|
connectionPreviews: toConnectionPreviews(detail),
|
|
33853
33898
|
previews: { assistantText: "", reasoningText: "" },
|
|
33854
33899
|
commandAuthorLabels: {},
|
|
33900
|
+
work: { items: [] },
|
|
33901
|
+
workTurnBaselines: {},
|
|
33855
33902
|
messageTurns: {},
|
|
33856
33903
|
retainedTurnStarts: {},
|
|
33857
33904
|
retainedTurnEnds: {}
|
|
@@ -34043,6 +34090,8 @@ function projectDurableAgentEvent({ state, event, occurredAt, retainedEventId })
|
|
|
34043
34090
|
const agentEvent = parseDurableAgentEvent(event);
|
|
34044
34091
|
if (agentEvent.type === "agent.message.ended")
|
|
34045
34092
|
return projectAgentMessageEnded({ state, event: agentEvent, occurredAt });
|
|
34093
|
+
if (agentEvent.type === "agent.work.observed" && agentEvent.actor.type === "main")
|
|
34094
|
+
return projectAgentWorkObserved({ state, event: agentEvent, occurredAt });
|
|
34046
34095
|
const stateWithTurnStart = agentEvent.type === "agent.turn.started" && agentEvent.actor.type === "main" ? {
|
|
34047
34096
|
...state,
|
|
34048
34097
|
retainedTurnStarts: { ...state.retainedTurnStarts, [agentEvent.turnId]: { actorType: agentEvent.actor.type, startedAt: occurredAt } },
|
|
@@ -34051,6 +34100,77 @@ function projectDurableAgentEvent({ state, event, occurredAt, retainedEventId })
|
|
|
34051
34100
|
const stateWithCompletedReasoning = agentEvent.type === "agent.reasoning.ended" ? { ...stateWithTurnStart, previews: { ...stateWithTurnStart.previews, reasoningText: "" } } : stateWithTurnStart;
|
|
34052
34101
|
return appendActivity({ state: stateWithCompletedReasoning, retainedEventId, occurredAt, card: toAgentActivityCard(agentEvent) });
|
|
34053
34102
|
}
|
|
34103
|
+
function projectAgentWorkObserved({
|
|
34104
|
+
state,
|
|
34105
|
+
event,
|
|
34106
|
+
occurredAt
|
|
34107
|
+
}) {
|
|
34108
|
+
const observations = event.payload.observations.map(sanitizeWorkObservation);
|
|
34109
|
+
const planIndex = state.transcript.findIndex((item) => item.kind === "plan" && item.turnId === event.turnId);
|
|
34110
|
+
const existingPlan = planIndex === -1 ? undefined : state.transcript[planIndex];
|
|
34111
|
+
const turnBaseline = state.workTurnBaselines[event.turnId] ?? state.work;
|
|
34112
|
+
let turnWork = { items: existingPlan?.items ?? [] };
|
|
34113
|
+
for (const observation of observations) {
|
|
34114
|
+
const itemId = patchedWorkItemId(observation);
|
|
34115
|
+
const priorItem = itemId === null ? undefined : turnBaseline.items.find((item) => item.id === itemId);
|
|
34116
|
+
if (priorItem && !turnWork.items.some((item) => item.id === itemId)) {
|
|
34117
|
+
turnWork = applyAgentWorkObservations(turnWork, [{
|
|
34118
|
+
kind: "item_observed",
|
|
34119
|
+
item: priorItem
|
|
34120
|
+
}]);
|
|
34121
|
+
}
|
|
34122
|
+
turnWork = applyAgentWorkObservations(turnWork, [observation]);
|
|
34123
|
+
}
|
|
34124
|
+
const plan = {
|
|
34125
|
+
kind: "plan",
|
|
34126
|
+
planId: `plan:${event.turnId}`,
|
|
34127
|
+
turnId: event.turnId,
|
|
34128
|
+
occurredAt: existingPlan?.occurredAt ?? occurredAt,
|
|
34129
|
+
items: turnWork.items
|
|
34130
|
+
};
|
|
34131
|
+
const transcript = planIndex === -1 ? [...state.transcript, plan] : state.transcript.map((item, index) => index === planIndex ? plan : item);
|
|
34132
|
+
return {
|
|
34133
|
+
...state,
|
|
34134
|
+
work: applyAgentWorkObservations(state.work, observations),
|
|
34135
|
+
workTurnBaselines: state.workTurnBaselines[event.turnId] ? state.workTurnBaselines : { ...state.workTurnBaselines, [event.turnId]: turnBaseline },
|
|
34136
|
+
latestWorkTurnId: event.turnId,
|
|
34137
|
+
transcript
|
|
34138
|
+
};
|
|
34139
|
+
}
|
|
34140
|
+
function sanitizeWorkObservation(observation) {
|
|
34141
|
+
switch (observation.kind) {
|
|
34142
|
+
case "snapshot":
|
|
34143
|
+
return {
|
|
34144
|
+
...observation,
|
|
34145
|
+
items: observation.items.map(sanitizeWorkItem)
|
|
34146
|
+
};
|
|
34147
|
+
case "item_observed":
|
|
34148
|
+
return {
|
|
34149
|
+
...observation,
|
|
34150
|
+
item: sanitizeWorkItem(observation.item)
|
|
34151
|
+
};
|
|
34152
|
+
case "item_renamed":
|
|
34153
|
+
return {
|
|
34154
|
+
...observation,
|
|
34155
|
+
title: providerText(observation.title, "Untitled task")
|
|
34156
|
+
};
|
|
34157
|
+
case "item_status_changed":
|
|
34158
|
+
case "item_removed":
|
|
34159
|
+
return observation;
|
|
34160
|
+
default: {
|
|
34161
|
+
const exhaustiveObservation = observation;
|
|
34162
|
+
return exhaustiveObservation;
|
|
34163
|
+
}
|
|
34164
|
+
}
|
|
34165
|
+
}
|
|
34166
|
+
function sanitizeWorkItem(item) {
|
|
34167
|
+
return { ...item, title: providerText(item.title, "Untitled task") };
|
|
34168
|
+
}
|
|
34169
|
+
function patchedWorkItemId(observation) {
|
|
34170
|
+
if (observation.kind === "item_renamed" || observation.kind === "item_status_changed")
|
|
34171
|
+
return observation.itemId;
|
|
34172
|
+
return null;
|
|
34173
|
+
}
|
|
34054
34174
|
function projectAgentMessageEnded({ state, event, occurredAt }) {
|
|
34055
34175
|
const messageId = event.payload.messageId;
|
|
34056
34176
|
if (state.transcript.some((item) => item.kind === "message" && item.messageId === messageId))
|
|
@@ -34163,9 +34283,10 @@ function publicMessageContentSegmentText(segment) {
|
|
|
34163
34283
|
function jsonDetail(value) {
|
|
34164
34284
|
return JSON.stringify(value);
|
|
34165
34285
|
}
|
|
34166
|
-
var ansiEscapePattern = /\u001B\[[0-9
|
|
34286
|
+
var ansiEscapePattern = /\u001B\[[0-9;:?]*[\u0020-\u002F]*[\u0040-\u007E]|\u009B[0-9;:?]*[\u0020-\u002F]*[\u0040-\u007E]|\u001B\][^\u0007]*?(?:\u0007|\u001B\\)|\u001B[0-9<=>\u0040-\u005A\u005C-\u005F]/g;
|
|
34287
|
+
var terminalControlPattern = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F]/g;
|
|
34167
34288
|
function stripAnsi(value) {
|
|
34168
|
-
return value.replace(ansiEscapePattern, "");
|
|
34289
|
+
return value.replace(ansiEscapePattern, "").replace(terminalControlPattern, "");
|
|
34169
34290
|
}
|
|
34170
34291
|
function providerText(raw, fallback) {
|
|
34171
34292
|
const cleaned = stripAnsi(raw ?? "").trim();
|
|
@@ -34740,6 +34861,7 @@ async function renderRemyView({
|
|
|
34740
34861
|
}
|
|
34741
34862
|
|
|
34742
34863
|
// src/tui/dashboard.ts
|
|
34864
|
+
var DASHBOARD_POLL_INTERVAL_MS = 1e4;
|
|
34743
34865
|
async function createDashboardTui({
|
|
34744
34866
|
initialPage,
|
|
34745
34867
|
loadPage,
|
|
@@ -34749,9 +34871,17 @@ async function createDashboardTui({
|
|
|
34749
34871
|
let inputHandler;
|
|
34750
34872
|
let keyHandler;
|
|
34751
34873
|
let resizeHandler;
|
|
34874
|
+
let refreshTimer;
|
|
34752
34875
|
let rendererDestroyed2 = false;
|
|
34876
|
+
const loadPageAbortController = new AbortController;
|
|
34753
34877
|
try {
|
|
34754
|
-
let
|
|
34878
|
+
let stopPageRefresh = function() {
|
|
34879
|
+
if (refreshTimer !== undefined) {
|
|
34880
|
+
clearInterval(refreshTimer);
|
|
34881
|
+
refreshTimer = undefined;
|
|
34882
|
+
}
|
|
34883
|
+
loadPageAbortController.abort();
|
|
34884
|
+
}, render = function() {
|
|
34755
34885
|
const contentWidth = renderer.width - 4;
|
|
34756
34886
|
const rowsBelow = rowsBelowVisibleWindow({ sessionCount: page.sessions.length, selectedIndex, height: renderer.height });
|
|
34757
34887
|
const isNarrow = renderer.width < 72;
|
|
@@ -34780,11 +34910,13 @@ async function createDashboardTui({
|
|
|
34780
34910
|
if (settled)
|
|
34781
34911
|
return;
|
|
34782
34912
|
settled = true;
|
|
34913
|
+
stopPageRefresh();
|
|
34783
34914
|
resolveAction(value);
|
|
34784
34915
|
}, fail = function(error93) {
|
|
34785
34916
|
if (settled)
|
|
34786
34917
|
return;
|
|
34787
34918
|
settled = true;
|
|
34919
|
+
stopPageRefresh();
|
|
34788
34920
|
rejectDraft(error93);
|
|
34789
34921
|
}, moveSelectionTo = function(index) {
|
|
34790
34922
|
if (page.sessions.length === 0)
|
|
@@ -34903,6 +35035,7 @@ async function createDashboardTui({
|
|
|
34903
35035
|
let pageIndex = 1;
|
|
34904
35036
|
let selectedIndex = 0;
|
|
34905
35037
|
let loadingPage = false;
|
|
35038
|
+
let pageRequestInFlight = false;
|
|
34906
35039
|
let pageError;
|
|
34907
35040
|
let awaitingVimGoToTop = false;
|
|
34908
35041
|
let logoutConfirmationOpen = false;
|
|
@@ -34920,23 +35053,53 @@ async function createDashboardTui({
|
|
|
34920
35053
|
rejectDraft = reject;
|
|
34921
35054
|
});
|
|
34922
35055
|
async function loadAdjacentPage(direction) {
|
|
34923
|
-
if (
|
|
35056
|
+
if (pageRequestInFlight)
|
|
34924
35057
|
return;
|
|
34925
35058
|
const canLoad = direction === "next" ? page.hasMore : page.canGoPrevious;
|
|
34926
35059
|
if (!canLoad)
|
|
34927
35060
|
return;
|
|
35061
|
+
pageRequestInFlight = true;
|
|
34928
35062
|
loadingPage = true;
|
|
34929
35063
|
pageError = undefined;
|
|
34930
35064
|
render();
|
|
34931
35065
|
try {
|
|
34932
|
-
|
|
35066
|
+
const loadedPage = await loadPage({ target: direction, signal: loadPageAbortController.signal });
|
|
35067
|
+
if (destroyed || settled)
|
|
35068
|
+
return;
|
|
35069
|
+
page = loadedPage;
|
|
34933
35070
|
pageIndex = Math.max(1, pageIndex + (direction === "next" ? 1 : -1));
|
|
34934
35071
|
selectedIndex = direction === "next" ? 0 : Math.max(0, page.sessions.length - 1);
|
|
34935
35072
|
} catch (error93) {
|
|
34936
|
-
|
|
35073
|
+
if (!destroyed && !settled)
|
|
35074
|
+
pageError = error93 instanceof Error ? error93.message : String(error93);
|
|
34937
35075
|
} finally {
|
|
35076
|
+
pageRequestInFlight = false;
|
|
34938
35077
|
loadingPage = false;
|
|
35078
|
+
if (!destroyed && !settled)
|
|
35079
|
+
render();
|
|
35080
|
+
}
|
|
35081
|
+
}
|
|
35082
|
+
async function refreshCurrentPage() {
|
|
35083
|
+
if (pageRequestInFlight || destroyed || settled)
|
|
35084
|
+
return;
|
|
35085
|
+
pageRequestInFlight = true;
|
|
35086
|
+
try {
|
|
35087
|
+
const refreshedPage = await loadPage({ target: "current", signal: loadPageAbortController.signal });
|
|
35088
|
+
if (destroyed || settled)
|
|
35089
|
+
return;
|
|
35090
|
+
const selectedSessionId = page.sessions[selectedIndex]?.id;
|
|
35091
|
+
page = refreshedPage;
|
|
35092
|
+
const refreshedSelectedIndex = selectedSessionId ? page.sessions.findIndex((session) => session.id === selectedSessionId) : -1;
|
|
35093
|
+
selectedIndex = refreshedSelectedIndex >= 0 ? refreshedSelectedIndex : Math.max(0, Math.min(selectedIndex, page.sessions.length - 1));
|
|
35094
|
+
pageError = undefined;
|
|
34939
35095
|
render();
|
|
35096
|
+
} catch (error93) {
|
|
35097
|
+
if (!destroyed && !settled) {
|
|
35098
|
+
pageError = error93 instanceof Error ? error93.message : String(error93);
|
|
35099
|
+
render();
|
|
35100
|
+
}
|
|
35101
|
+
} finally {
|
|
35102
|
+
pageRequestInFlight = false;
|
|
34940
35103
|
}
|
|
34941
35104
|
}
|
|
34942
35105
|
async function moveSelection(direction) {
|
|
@@ -34968,6 +35131,9 @@ async function createDashboardTui({
|
|
|
34968
35131
|
renderer.on(CliRenderEvents2.RESIZE, resizeHandler);
|
|
34969
35132
|
render();
|
|
34970
35133
|
listRegion.focus();
|
|
35134
|
+
refreshTimer = setInterval(() => {
|
|
35135
|
+
refreshCurrentPage();
|
|
35136
|
+
}, DASHBOARD_POLL_INTERVAL_MS);
|
|
34971
35137
|
return {
|
|
34972
35138
|
waitForAction: async () => await action,
|
|
34973
35139
|
destroy() {
|
|
@@ -34980,6 +35146,7 @@ async function createDashboardTui({
|
|
|
34980
35146
|
renderer.keyInput.off("keypress", keyHandler);
|
|
34981
35147
|
if (resizeHandler)
|
|
34982
35148
|
renderer.off(CliRenderEvents2.RESIZE, resizeHandler);
|
|
35149
|
+
stopPageRefresh();
|
|
34983
35150
|
rendererDestroyed2 = true;
|
|
34984
35151
|
renderer.destroy();
|
|
34985
35152
|
},
|
|
@@ -34994,6 +35161,9 @@ async function createDashboardTui({
|
|
|
34994
35161
|
renderer.keyInput.off("keypress", keyHandler);
|
|
34995
35162
|
if (resizeHandler)
|
|
34996
35163
|
renderer.off(CliRenderEvents2.RESIZE, resizeHandler);
|
|
35164
|
+
if (refreshTimer !== undefined)
|
|
35165
|
+
clearInterval(refreshTimer);
|
|
35166
|
+
loadPageAbortController.abort();
|
|
34997
35167
|
if (!rendererDestroyed2) {
|
|
34998
35168
|
rendererDestroyed2 = true;
|
|
34999
35169
|
renderer.destroy();
|
|
@@ -35292,20 +35462,6 @@ function activePathToken(text) {
|
|
|
35292
35462
|
return match?.[1];
|
|
35293
35463
|
}
|
|
35294
35464
|
|
|
35295
|
-
// src/session-agent-options.ts
|
|
35296
|
-
function newSessionModelLabel(model) {
|
|
35297
|
-
return codexModelPresentation[model].label;
|
|
35298
|
-
}
|
|
35299
|
-
function newSessionReasoningEffortLabel(effort) {
|
|
35300
|
-
return agentReasoningEffortPresentation[effort].label;
|
|
35301
|
-
}
|
|
35302
|
-
var newSessionModels = codexModelIds;
|
|
35303
|
-
var newSessionReasoningEfforts = selectableAgentReasoningEfforts;
|
|
35304
|
-
var defaultNewSessionAgent = {
|
|
35305
|
-
model: codexModelIds[0],
|
|
35306
|
-
reasoningEffort: "medium"
|
|
35307
|
-
};
|
|
35308
|
-
|
|
35309
35465
|
// src/tui/new-session-wizard.ts
|
|
35310
35466
|
var suggestionSpinnerFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
35311
35467
|
var suggestionSpinnerIntervalMs = 80;
|
|
@@ -36211,7 +36367,19 @@ async function createSessionTui({
|
|
|
36211
36367
|
}
|
|
36212
36368
|
return count;
|
|
36213
36369
|
}, turnDividerLabel = function() {
|
|
36214
|
-
|
|
36370
|
+
const working = isRemyWorking(latestState);
|
|
36371
|
+
const planItems = pinnedPlanItems(latestState);
|
|
36372
|
+
if (planItems.length > 0) {
|
|
36373
|
+
const completed = planItems.filter((item) => item.status === "completed").length;
|
|
36374
|
+
const current = planItems.find((item) => item.status === "in_progress") ?? planItems.find((item) => item.status === "pending");
|
|
36375
|
+
if (stopState.kind === "stopping")
|
|
36376
|
+
return renderer.width < 76 ? `Plan ${completed}/${planItems.length} \xB7 stopping\u2026` : `Plan ${completed}/${planItems.length} \xB7 stopping the turn\u2026`;
|
|
36377
|
+
if (renderer.width < 84)
|
|
36378
|
+
return `Plan ${completed}/${planItems.length} \xB7 ctrl+o${working ? " \xB7 esc stop" : ""}`;
|
|
36379
|
+
const currentLabel = current ? ` \xB7 ${truncate2(current.title, 20)}` : "";
|
|
36380
|
+
return `Plan ${completed}/${planItems.length}${currentLabel} \xB7 ctrl+o details${working ? " \xB7 esc to stop" : ""}`;
|
|
36381
|
+
}
|
|
36382
|
+
if (!working)
|
|
36215
36383
|
return;
|
|
36216
36384
|
if (stopState.kind === "stopping")
|
|
36217
36385
|
return renderer.width < 76 ? "stopping\u2026" : "stopping the turn\u2026";
|
|
@@ -36989,6 +37157,12 @@ function workingTurnStartedAt(state) {
|
|
|
36989
37157
|
return activeTurn.startedAt;
|
|
36990
37158
|
return Object.values(state.messageTurns).find((turn) => turn.outcome === undefined && turn.startedAt !== undefined)?.startedAt;
|
|
36991
37159
|
}
|
|
37160
|
+
function pinnedPlanItems(state) {
|
|
37161
|
+
if (state.aggregateStatus !== "open" || state.work.items.length === 0 || state.latestWorkTurnId === undefined)
|
|
37162
|
+
return [];
|
|
37163
|
+
const hasIncompleteItem = state.work.items.some((item) => item.status !== "completed");
|
|
37164
|
+
return !hasIncompleteItem && state.retainedTurnEnds[state.latestWorkTurnId] ? [] : state.work.items;
|
|
37165
|
+
}
|
|
36992
37166
|
var collapsedActivityTailLength = 3;
|
|
36993
37167
|
function isSignalActivity(item) {
|
|
36994
37168
|
return item.card.weight === "signal";
|
|
@@ -37009,12 +37183,12 @@ function renderTimeline({ state, activityExpanded }) {
|
|
|
37009
37183
|
}
|
|
37010
37184
|
groups.push({ kind: "single", item });
|
|
37011
37185
|
}
|
|
37012
|
-
const blocks = groups.map((group) => group.kind === "single" ? renderTimelineItem(group.item) : renderActivityGroup({ items: group.items, activityExpanded }));
|
|
37186
|
+
const blocks = groups.map((group) => group.kind === "single" ? renderTimelineItem(group.item, activityExpanded) : renderActivityGroup({ items: group.items, activityExpanded }));
|
|
37013
37187
|
return joinStyled(blocks.filter((block) => block.chunks.length > 0), `
|
|
37014
37188
|
|
|
37015
37189
|
`);
|
|
37016
37190
|
}
|
|
37017
|
-
function renderTimelineItem(item) {
|
|
37191
|
+
function renderTimelineItem(item, activityExpanded) {
|
|
37018
37192
|
if (item.kind === "message") {
|
|
37019
37193
|
const header = new StyledText5([
|
|
37020
37194
|
renderTimestampChunk(item.occurredAt),
|
|
@@ -37024,12 +37198,53 @@ function renderTimelineItem(item) {
|
|
|
37024
37198
|
return joinStyled([header, renderMessageBody({ text: item.text, role: item.author.role })], `
|
|
37025
37199
|
`);
|
|
37026
37200
|
}
|
|
37201
|
+
if (item.kind === "plan")
|
|
37202
|
+
return renderPlan({ item, expanded: activityExpanded });
|
|
37027
37203
|
return new StyledText5([
|
|
37028
37204
|
renderTimestampChunk(item.occurredAt),
|
|
37029
37205
|
bold4(fg6(PALETTE.tool)("Artifact: ")),
|
|
37030
37206
|
fg6(PALETTE.bodyText)(item.filename)
|
|
37031
37207
|
]);
|
|
37032
37208
|
}
|
|
37209
|
+
var collapsedPlanItemLimit = 5;
|
|
37210
|
+
function renderPlan({ item, expanded }) {
|
|
37211
|
+
if (item.items.length === 0)
|
|
37212
|
+
return new StyledText5([]);
|
|
37213
|
+
const completed = item.items.filter((workItem) => workItem.status === "completed").length;
|
|
37214
|
+
const visibleItems = expanded ? item.items : collapsedPlanItems(item.items);
|
|
37215
|
+
const rows = visibleItems.map((workItem) => {
|
|
37216
|
+
if (workItem.status === "in_progress") {
|
|
37217
|
+
return new StyledText5([
|
|
37218
|
+
fg6(PALETTE.remyAccent)(" \u25B8 "),
|
|
37219
|
+
bold4(fg6(PALETTE.bodyText)(workItem.title))
|
|
37220
|
+
]);
|
|
37221
|
+
}
|
|
37222
|
+
const glyph = workItem.status === "completed" ? "\u2713" : "\u25CB";
|
|
37223
|
+
return new StyledText5([
|
|
37224
|
+
fg6(PALETTE.dimText)(` ${glyph} `),
|
|
37225
|
+
dim4(fg6(PALETTE.dimText)(workItem.title))
|
|
37226
|
+
]);
|
|
37227
|
+
});
|
|
37228
|
+
const hidden = item.items.length - visibleItems.length;
|
|
37229
|
+
return joinStyled([
|
|
37230
|
+
new StyledText5([
|
|
37231
|
+
renderTimestampChunk(item.occurredAt),
|
|
37232
|
+
bold4(fg6(PALETTE.remyAccent)("Plan")),
|
|
37233
|
+
dim4(fg6(PALETTE.dimText)(` \xB7 ${completed}/${item.items.length} done`))
|
|
37234
|
+
]),
|
|
37235
|
+
...rows,
|
|
37236
|
+
...hidden > 0 ? [new StyledText5([dim4(fg6(PALETTE.dimText)(` \u2026 ${hidden} more task${hidden === 1 ? "" : "s"} \xB7 Ctrl+O details`))])] : []
|
|
37237
|
+
], `
|
|
37238
|
+
`);
|
|
37239
|
+
}
|
|
37240
|
+
function collapsedPlanItems(items) {
|
|
37241
|
+
if (items.length <= collapsedPlanItemLimit)
|
|
37242
|
+
return items;
|
|
37243
|
+
const current = items.find((item) => item.status === "in_progress");
|
|
37244
|
+
if (!current || items.slice(0, collapsedPlanItemLimit).some((item) => item.id === current.id))
|
|
37245
|
+
return items.slice(0, collapsedPlanItemLimit);
|
|
37246
|
+
return [...items.slice(0, collapsedPlanItemLimit - 1), current];
|
|
37247
|
+
}
|
|
37033
37248
|
var boilerplateActivitySummaries = new Set([
|
|
37034
37249
|
"Tool started.",
|
|
37035
37250
|
"Tool completed.",
|
|
@@ -37159,6 +37374,11 @@ function formatElapsed(elapsedMs) {
|
|
|
37159
37374
|
return `${totalSeconds}s`;
|
|
37160
37375
|
return `${Math.floor(totalSeconds / 60)}m ${totalSeconds % 60}s`;
|
|
37161
37376
|
}
|
|
37377
|
+
function truncate2(value, width) {
|
|
37378
|
+
if (value.length <= width)
|
|
37379
|
+
return value;
|
|
37380
|
+
return `${value.slice(0, Math.max(0, width - 1))}\u2026`;
|
|
37381
|
+
}
|
|
37162
37382
|
function renderComposerStatus({ admittedSubmissions }) {
|
|
37163
37383
|
if (admittedSubmissions.length === 0)
|
|
37164
37384
|
return new StyledText5([]);
|
|
@@ -37294,7 +37514,7 @@ var compactMarkRows = 9;
|
|
|
37294
37514
|
var compactMinWidth = 48;
|
|
37295
37515
|
var compactMinHeight = 20;
|
|
37296
37516
|
var markBrightnessGain = 4.2;
|
|
37297
|
-
var remyCliVersion = "1.
|
|
37517
|
+
var remyCliVersion = "1.6.0";
|
|
37298
37518
|
async function showRemySplash({
|
|
37299
37519
|
createRenderer = createRemyRenderer,
|
|
37300
37520
|
durationMs = splashDurationMs,
|
|
@@ -38073,18 +38293,34 @@ async function dashboard({
|
|
|
38073
38293
|
function holdTransitionScreen() {
|
|
38074
38294
|
showRemyTransitionScreen({ write: (chunk) => dependencies.output.writeStdout(chunk) });
|
|
38075
38295
|
}
|
|
38076
|
-
async function loadDashboardPage({
|
|
38296
|
+
async function loadDashboardPage({ target, signal }) {
|
|
38077
38297
|
if (loadingPage)
|
|
38078
38298
|
return await loadingPage;
|
|
38079
38299
|
loadingPage = (async () => {
|
|
38080
|
-
if (
|
|
38300
|
+
if (target === "current") {
|
|
38301
|
+
const after = pageIndex > 0 ? pages[pageIndex - 1]?.nextCursor ?? undefined : undefined;
|
|
38302
|
+
const refreshed = toDashboardPage(await operations.listSessions({
|
|
38303
|
+
client: operations.client,
|
|
38304
|
+
limit: 20,
|
|
38305
|
+
after,
|
|
38306
|
+
signal
|
|
38307
|
+
}));
|
|
38308
|
+
pages.splice(pageIndex, pages.length - pageIndex, refreshed);
|
|
38309
|
+
return { ...refreshed, canGoPrevious: pageIndex > 0 };
|
|
38310
|
+
}
|
|
38311
|
+
if (target === "previous") {
|
|
38081
38312
|
pageIndex = Math.max(0, pageIndex - 1);
|
|
38082
38313
|
return { ...pages[pageIndex], canGoPrevious: pageIndex > 0 };
|
|
38083
38314
|
}
|
|
38084
38315
|
const current = pages[pageIndex];
|
|
38085
38316
|
if (!current.hasMore || !current.nextCursor)
|
|
38086
38317
|
return { ...current, canGoPrevious: pageIndex > 0 };
|
|
38087
|
-
const next = toDashboardPage(await operations.listSessions({
|
|
38318
|
+
const next = toDashboardPage(await operations.listSessions({
|
|
38319
|
+
client: operations.client,
|
|
38320
|
+
limit: 20,
|
|
38321
|
+
after: current.nextCursor,
|
|
38322
|
+
signal
|
|
38323
|
+
}));
|
|
38088
38324
|
pages.splice(pageIndex + 1);
|
|
38089
38325
|
pages.push(next);
|
|
38090
38326
|
pageIndex += 1;
|
|
@@ -38100,7 +38336,11 @@ async function dashboard({
|
|
|
38100
38336
|
holdTransitionScreen();
|
|
38101
38337
|
while (true) {
|
|
38102
38338
|
if (!firstOpen) {
|
|
38103
|
-
pages.splice(0, pages.length, toDashboardPage(await operations.listSessions({
|
|
38339
|
+
pages.splice(0, pages.length, toDashboardPage(await operations.listSessions({
|
|
38340
|
+
client: operations.client,
|
|
38341
|
+
limit: 20,
|
|
38342
|
+
signal: dependencies.abortSignal
|
|
38343
|
+
})));
|
|
38104
38344
|
pageIndex = 0;
|
|
38105
38345
|
}
|
|
38106
38346
|
firstOpen = false;
|
|
@@ -38362,7 +38602,7 @@ async function createNewSession({
|
|
|
38362
38602
|
prompt: command.prompt,
|
|
38363
38603
|
fileIds,
|
|
38364
38604
|
...command.model ? { model: command.model } : {},
|
|
38365
|
-
|
|
38605
|
+
reasoningEffort: command.reasoningEffort ?? defaultNewSessionAgent.reasoningEffort,
|
|
38366
38606
|
idempotencyKey: randomUUID5()
|
|
38367
38607
|
}
|
|
38368
38608
|
});
|