@meistrari/remy-cli 1.15.0 → 1.17.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 +15 -1
- package/dist/remy.js +227 -61
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,6 +54,8 @@ Published files and Tela Pages appear in the timeline. File artifacts include th
|
|
|
54
54
|
|
|
55
55
|
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.
|
|
56
56
|
|
|
57
|
+
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.
|
|
58
|
+
|
|
57
59
|
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. Remy does not fetch or print artifact bytes. When the conversation has focus, press `Tab` to return to the composer.
|
|
58
60
|
|
|
59
61
|
| Control | Result |
|
|
@@ -61,6 +63,7 @@ Drag to select visible text in any Remy view; Remy copies it to the local clipbo
|
|
|
61
63
|
| `Esc` | Interrupt the active turn; the session stays open. |
|
|
62
64
|
| `/complete` | Complete an open session after its active turn stops. |
|
|
63
65
|
| `/cancel` | Cancel the current session, including an active turn. |
|
|
66
|
+
| `/compact` | Admit a main-thread context compaction request without sending a message; the provider result appears in retained activity. |
|
|
64
67
|
| `/sessions` | Return to the dashboard. |
|
|
65
68
|
| `/new` | Start another new-session flow. |
|
|
66
69
|
| `/logout` | Sign out of Remy after confirmation. |
|
|
@@ -99,6 +102,14 @@ The branch-suggestion flow belongs to the interactive new-session wizard (`remy`
|
|
|
99
102
|
remy --session <session-id>
|
|
100
103
|
```
|
|
101
104
|
|
|
105
|
+
To submit a follow-up immediately, add one quoted positional `prompt`:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
remy --session <session-id> "Add regression coverage for that fix"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Remy sends the prompt as **Steer**, then opens the conversation. Omitting the prompt only attaches. An explicitly empty prompt is rejected. Use `--` before a prompt beginning with `--` to treat it as text.
|
|
112
|
+
|
|
102
113
|
### Automate a session
|
|
103
114
|
|
|
104
115
|
`remy new` and `remy --session` use JSON Lines output automatically when standard input or output is not a terminal. Pass `--no-tui` to choose that mode explicitly; `--json` also selects it.
|
|
@@ -108,8 +119,11 @@ Opaque session and message metadata returned by the API is accepted for compatib
|
|
|
108
119
|
```bash
|
|
109
120
|
remy new --no-tui --repository owner/repository "Add a health check endpoint"
|
|
110
121
|
remy --session <session-id> --json
|
|
122
|
+
remy --session <session-id> --no-tui "Add regression coverage for that fix"
|
|
111
123
|
```
|
|
112
124
|
|
|
125
|
+
With a follow-up prompt, Remy submits it once and streams JSON Lines until that message reaches a terminal outcome, even if a previous message is cached locally. It exits with status `0` for a completed turn or `1` for another terminal outcome or an API failure. A follow-up does not emit a `created` record because the session already exists. If the local session cache becomes unavailable after admission, Remy warns once and continues observing the accepted follow-up in memory. Do not resubmit the prompt because of that warning; local resume metadata may remain stale. These commands require prior sign-in and can be used by scripts or other agents.
|
|
126
|
+
|
|
113
127
|
For a newly created session, Remy writes a `created` record, event-name records as they arrive, then a `terminal` record when the submitted turn settles. A completed turn exits with status `0`; another terminal outcome exits with status `1`.
|
|
114
128
|
|
|
115
129
|
```json
|
|
@@ -151,7 +165,7 @@ remy logout [--api-url <url>]
|
|
|
151
165
|
remy whoami
|
|
152
166
|
remy dashboard
|
|
153
167
|
remy new [--repository <owner/name> ... --installation <id> --model <name> --reasoning-effort <low|medium|high|xhigh> --attach <path> ... --no-tui --json] <prompt>
|
|
154
|
-
remy --session <session-id> [--no-tui] [--json]
|
|
168
|
+
remy --session <session-id> [--no-tui] [--json] [prompt]
|
|
155
169
|
```
|
|
156
170
|
|
|
157
171
|
Run `remy <command> --help` for flags and command-specific usage. `remy whoami` prints the saved signed-in identity and organization.
|
package/dist/remy.js
CHANGED
|
@@ -32214,6 +32214,10 @@ var interruptAgentCommandSchema = runningCommandBaseSchema.extend({
|
|
|
32214
32214
|
turnId: zod_default2.string().min(1).optional(),
|
|
32215
32215
|
reason: zod_default2.string().min(1).optional()
|
|
32216
32216
|
}).strict();
|
|
32217
|
+
var compactContextAgentCommandSchema = runningCommandBaseSchema.extend({
|
|
32218
|
+
type: zod_default2.literal("agent.compact-context"),
|
|
32219
|
+
commandId: commandIdSchema
|
|
32220
|
+
}).strict();
|
|
32217
32221
|
var stopAgentCommandSchema = runningCommandBaseSchema.extend({
|
|
32218
32222
|
type: zod_default2.literal("agent.stop"),
|
|
32219
32223
|
reason: zod_default2.string().min(1).optional()
|
|
@@ -32227,6 +32231,7 @@ var respondUserInputAgentCommandSchema = runningCommandBaseSchema.extend({
|
|
|
32227
32231
|
var agentCommandSchema = zod_default2.union([
|
|
32228
32232
|
sendPromptCommandSchema,
|
|
32229
32233
|
interruptAgentCommandSchema,
|
|
32234
|
+
compactContextAgentCommandSchema,
|
|
32230
32235
|
stopAgentCommandSchema,
|
|
32231
32236
|
respondUserInputAgentCommandSchema
|
|
32232
32237
|
]);
|
|
@@ -32420,6 +32425,12 @@ var agentTurnEndStatusSchema = zod_default2.enum(["completed", "failed", "cancel
|
|
|
32420
32425
|
var agentSubagentStatusSchema = zod_default2.enum(["completed", "failed", "cancelled"]);
|
|
32421
32426
|
var agentContextCompactionTriggerSchema = zod_default2.enum(["manual", "auto", "unknown"]);
|
|
32422
32427
|
var agentContextCompactionStatusSchema = zod_default2.enum(["completed", "failed"]);
|
|
32428
|
+
var agentContextCompactionRequestResultSchema = zod_default2.discriminatedUnion("status", [
|
|
32429
|
+
zod_default2.object({ status: zod_default2.literal("completed") }).strict(),
|
|
32430
|
+
zod_default2.object({ status: zod_default2.literal("no_op"), reason: zod_default2.string() }).strict(),
|
|
32431
|
+
zod_default2.object({ status: zod_default2.literal("failed"), error: agentErrorSchema }).strict(),
|
|
32432
|
+
zod_default2.object({ status: zod_default2.literal("unknown") }).strict()
|
|
32433
|
+
]);
|
|
32423
32434
|
var agentErrorSourceSchema = zod_default2.enum(["provider", "runtime", "transport", "unknown"]);
|
|
32424
32435
|
var agentSkillScopeSchema = zod_default2.enum(["user", "repository", "system", "admin"]);
|
|
32425
32436
|
var agentSkillSchema = zod_default2.object({
|
|
@@ -32672,6 +32683,13 @@ var contextCompactionCompletedAgentEventSchema = agentTurnEventBaseSchema.extend
|
|
|
32672
32683
|
error: agentErrorSchema.optional()
|
|
32673
32684
|
}).strict()
|
|
32674
32685
|
}).strict();
|
|
32686
|
+
var contextCompactionRequestCompletedAgentEventSchema = agentEventBaseSchema.extend({
|
|
32687
|
+
type: zod_default2.literal("context.compaction.request.completed"),
|
|
32688
|
+
payload: zod_default2.object({
|
|
32689
|
+
commandId: zod_default2.string().min(1),
|
|
32690
|
+
result: agentContextCompactionRequestResultSchema
|
|
32691
|
+
}).strict()
|
|
32692
|
+
}).strict();
|
|
32675
32693
|
var userInputRequestedAgentEventSchema = agentTurnEventBaseSchema.extend({
|
|
32676
32694
|
type: zod_default2.literal("user-input.requested"),
|
|
32677
32695
|
payload: zod_default2.object({
|
|
@@ -32724,6 +32742,7 @@ var agentEventSchema = zod_default2.discriminatedUnion("type", [
|
|
|
32724
32742
|
contextUpdatedAgentEventSchema,
|
|
32725
32743
|
contextCompactionStartedAgentEventSchema,
|
|
32726
32744
|
contextCompactionCompletedAgentEventSchema,
|
|
32745
|
+
contextCompactionRequestCompletedAgentEventSchema,
|
|
32727
32746
|
userInputRequestedAgentEventSchema,
|
|
32728
32747
|
userInputResolvedAgentEventSchema,
|
|
32729
32748
|
errorAgentEventSchema
|
|
@@ -32912,6 +32931,13 @@ var interruptSessionResponseSchema = exports_external2.strictObject({
|
|
|
32912
32931
|
type: exports_external2.literal("agent.interrupt")
|
|
32913
32932
|
})
|
|
32914
32933
|
});
|
|
32934
|
+
var compactSessionContextResponseSchema = exports_external2.strictObject({
|
|
32935
|
+
command: exports_external2.strictObject({
|
|
32936
|
+
id: exports_external2.string(),
|
|
32937
|
+
sequence: exports_external2.number().int().positive(),
|
|
32938
|
+
type: exports_external2.literal("agent.compact-context")
|
|
32939
|
+
})
|
|
32940
|
+
});
|
|
32915
32941
|
var withdrawSessionMessageResponseSchema = exports_external2.strictObject({
|
|
32916
32942
|
command: exports_external2.strictObject({
|
|
32917
32943
|
id: exports_external2.string(),
|
|
@@ -33082,6 +33108,24 @@ async function interruptSession({
|
|
|
33082
33108
|
throw new CodingAgentProtocolError("Session interrupt response did not match the public API contract.", { cause: parsed.error });
|
|
33083
33109
|
return parsed.data.command;
|
|
33084
33110
|
}
|
|
33111
|
+
async function compactSessionContext({
|
|
33112
|
+
client,
|
|
33113
|
+
sessionId,
|
|
33114
|
+
idempotencyKey
|
|
33115
|
+
}) {
|
|
33116
|
+
const response = await client.request(`/v1/sessions/${encodeURIComponent(sessionId)}/compact`, {
|
|
33117
|
+
method: "POST",
|
|
33118
|
+
headers: {
|
|
33119
|
+
"content-type": "application/json",
|
|
33120
|
+
"Idempotency-Key": idempotencyKey
|
|
33121
|
+
},
|
|
33122
|
+
body: "{}"
|
|
33123
|
+
});
|
|
33124
|
+
const parsed = compactSessionContextResponseSchema.safeParse(await parseJson2(response, "Session context compaction response was not valid JSON."));
|
|
33125
|
+
if (!parsed.success)
|
|
33126
|
+
throw new CodingAgentProtocolError("Session context compaction response did not match the public API contract.", { cause: parsed.error });
|
|
33127
|
+
return parsed.data.command;
|
|
33128
|
+
}
|
|
33085
33129
|
async function completeSession({ client, sessionId }) {
|
|
33086
33130
|
const response = await client.request(`/v1/sessions/${encodeURIComponent(sessionId)}/complete`, { method: "PUT" });
|
|
33087
33131
|
const parsed = sessionDetailResponseSchema.safeParse(await parseJson2(response, "Session completion response was not valid JSON."));
|
|
@@ -34022,6 +34066,9 @@ var wrappedContextCompactionStartedAgentEventSchema = contextCompactionStartedAg
|
|
|
34022
34066
|
var wrappedContextCompactionCompletedAgentEventSchema = contextCompactionCompletedAgentEventSchema.extend({
|
|
34023
34067
|
type: zod_default2.literal("agent.context.compaction.completed")
|
|
34024
34068
|
}).strict();
|
|
34069
|
+
var wrappedContextCompactionRequestCompletedAgentEventSchema = contextCompactionRequestCompletedAgentEventSchema.extend({
|
|
34070
|
+
type: zod_default2.literal("agent.context.compaction.request.completed")
|
|
34071
|
+
}).strict();
|
|
34025
34072
|
var wrappedUserInputRequestedAgentEventSchema = userInputRequestedAgentEventSchema.extend({
|
|
34026
34073
|
type: zod_default2.literal("agent.user-input.requested")
|
|
34027
34074
|
}).strict();
|
|
@@ -34056,11 +34103,31 @@ var wrappedAgentEventSchema = zod_default2.discriminatedUnion("type", [
|
|
|
34056
34103
|
wrappedContextUpdatedAgentEventSchema,
|
|
34057
34104
|
wrappedContextCompactionStartedAgentEventSchema,
|
|
34058
34105
|
wrappedContextCompactionCompletedAgentEventSchema,
|
|
34106
|
+
wrappedContextCompactionRequestCompletedAgentEventSchema,
|
|
34059
34107
|
wrappedUserInputRequestedAgentEventSchema,
|
|
34060
34108
|
wrappedUserInputResolvedAgentEventSchema,
|
|
34061
34109
|
wrappedErrorAgentEventSchema
|
|
34062
34110
|
]);
|
|
34063
34111
|
|
|
34112
|
+
// ../../packages/agents-protocol/src/agent-identity.ts
|
|
34113
|
+
function normalizeAgentSubagentIdentity(identity) {
|
|
34114
|
+
return {
|
|
34115
|
+
actorId: identity.actorId,
|
|
34116
|
+
subagentId: identity.subagentId,
|
|
34117
|
+
parentActorId: identity.parentActorId,
|
|
34118
|
+
origin: identity.origin,
|
|
34119
|
+
parentToolCallId: identity.parentToolCallId ?? (identity.origin.type === "tool_call" ? identity.origin.toolCallId : undefined)
|
|
34120
|
+
};
|
|
34121
|
+
}
|
|
34122
|
+
function agentSubagentIdentitiesEqual(left, right) {
|
|
34123
|
+
const normalizedLeft = normalizeAgentSubagentIdentity(left);
|
|
34124
|
+
const normalizedRight = normalizeAgentSubagentIdentity(right);
|
|
34125
|
+
return normalizedLeft.actorId === normalizedRight.actorId && normalizedLeft.subagentId === normalizedRight.subagentId && normalizedLeft.parentActorId === normalizedRight.parentActorId && normalizedLeft.parentToolCallId === normalizedRight.parentToolCallId && (normalizedLeft.origin.type === "tool_call" ? normalizedRight.origin.type === "tool_call" && normalizedLeft.origin.toolCallId === normalizedRight.origin.toolCallId : normalizedRight.origin.type === "provider_task" && normalizedLeft.origin.taskId === normalizedRight.origin.taskId);
|
|
34126
|
+
}
|
|
34127
|
+
function agentRuntimeIdentityKey(event) {
|
|
34128
|
+
return `${event.sessionId.length}:${event.sessionId}:${event.providerSessionId.length}:${event.providerSessionId}`;
|
|
34129
|
+
}
|
|
34130
|
+
|
|
34064
34131
|
// src/sessions/projection.ts
|
|
34065
34132
|
var sessionMessageCreatedEventSchema = exports_external2.object({
|
|
34066
34133
|
type: exports_external2.literal("session.message.created"),
|
|
@@ -34389,11 +34456,7 @@ function projectAgentTurnEnded({ state, event, occurredAt, retainedEventId }) {
|
|
|
34389
34456
|
retainedTurnEnds: { ...state.retainedTurnEnds, [event.turnId]: { actorType: event.actor.type, outcome: event.payload.status } },
|
|
34390
34457
|
messageTurns: Object.fromEntries(Object.entries(state.messageTurns).map(([messageId, turn]) => [messageId, turn.turnId === event.turnId ? { ...turn, outcome: event.payload.status } : turn]))
|
|
34391
34458
|
} : state;
|
|
34392
|
-
const card = event
|
|
34393
|
-
identity: event.actor,
|
|
34394
|
-
activityTitle: event.payload.status === "failed" ? "Turn failed" : "Turn ended",
|
|
34395
|
-
card: event.payload.status === "failed" ? { kind: "failure", weight: "signal", summary: providerText(event.payload.error?.message, "Turn failed.") } : { kind: "lifecycle", weight: "noise", summary: `Turn ${event.payload.status}.` }
|
|
34396
|
-
});
|
|
34459
|
+
const card = toAgentActivityCard(event);
|
|
34397
34460
|
return appendActivity({ state: stateWithTurnOutcome, retainedEventId, occurredAt, card });
|
|
34398
34461
|
}
|
|
34399
34462
|
function projectDurableAgentEvent({ state, event, occurredAt, retainedEventId }) {
|
|
@@ -34538,7 +34601,7 @@ function toMainAgentActivityCard(event) {
|
|
|
34538
34601
|
case "agent.turn.started":
|
|
34539
34602
|
return { kind: "lifecycle", weight: "noise", title: "Remy turn started", summary: "Turn started." };
|
|
34540
34603
|
case "agent.turn.ended":
|
|
34541
|
-
return event.payload.status === "failed" ? { kind: "failure", weight: "signal", title: "Remy turn failed", summary:
|
|
34604
|
+
return event.payload.status === "failed" ? { kind: "failure", weight: "signal", title: "Remy turn failed", summary: "Turn failed." } : { kind: "lifecycle", weight: "noise", title: "Remy turn ended", summary: `Turn ${event.payload.status}.` };
|
|
34542
34605
|
case "agent.work.observed":
|
|
34543
34606
|
return { kind: "progress", weight: "noise", title: "Work progress", summary: "Remy updated its work plan.", detail: jsonDetail(event.payload.observations) };
|
|
34544
34607
|
case "agent.message.started":
|
|
@@ -34574,6 +34637,16 @@ function toMainAgentActivityCard(event) {
|
|
|
34574
34637
|
return { kind: "reasoning", weight: "noise", title: "Context compaction started", summary: "Remy is compacting context." };
|
|
34575
34638
|
case "agent.context.compaction.completed":
|
|
34576
34639
|
return event.payload.status === "failed" ? { kind: "failure", weight: "signal", title: "Context compaction failed", summary: providerText(event.payload.error?.message, "Context compaction failed.") } : { kind: "reasoning", weight: "noise", title: "Context compaction completed", summary: "Remy compacted context." };
|
|
34640
|
+
case "agent.context.compaction.request.completed": {
|
|
34641
|
+
const result = event.payload.result;
|
|
34642
|
+
if (result.status === "completed")
|
|
34643
|
+
return { kind: "progress", weight: "signal", title: "Context compaction completed", summary: "The provider completed manual context compaction." };
|
|
34644
|
+
if (result.status === "no_op")
|
|
34645
|
+
return { kind: "progress", weight: "signal", title: "Context not compacted", summary: providerText(result.reason, "The provider did not compact context.") };
|
|
34646
|
+
if (result.status === "failed")
|
|
34647
|
+
return { kind: "failure", weight: "signal", title: "Context compaction failed", summary: providerText(result.error.message, "Context compaction failed.") };
|
|
34648
|
+
return { kind: "progress", weight: "signal", title: "Context compaction result unknown", summary: "The provider result could not be correlated." };
|
|
34649
|
+
}
|
|
34577
34650
|
case "agent.user-input.requested":
|
|
34578
34651
|
return { kind: "approval-question", weight: "signal", title: "Remy needs input", summary: providerText(event.payload.prompt, "Remy needs input."), detail: jsonDetail(event.payload.questions) };
|
|
34579
34652
|
case "agent.user-input.resolved":
|
|
@@ -34659,6 +34732,7 @@ function toChildAgentActivityCard({ event, identity }) {
|
|
|
34659
34732
|
case "agent.session.skills.updated":
|
|
34660
34733
|
case "agent.session.state.changed":
|
|
34661
34734
|
case "agent.session.ended":
|
|
34735
|
+
case "agent.context.compaction.request.completed":
|
|
34662
34736
|
case "agent.user-input.resolved":
|
|
34663
34737
|
case "agent.error":
|
|
34664
34738
|
throw new SessionProjectionProtocolError(`Cannot attribute non-child session event type ${event.type} to a subagent.`);
|
|
@@ -34701,7 +34775,7 @@ ${card.detail}`;
|
|
|
34701
34775
|
function childActivityIdentity(event) {
|
|
34702
34776
|
if (event.type === "agent.subagent.started" || event.type === "agent.subagent.progress" || event.type === "agent.subagent.ended") {
|
|
34703
34777
|
if (event.actor.type === "subagent") {
|
|
34704
|
-
if (!
|
|
34778
|
+
if (!agentSubagentIdentitiesEqual(event.actor, event.payload))
|
|
34705
34779
|
throw new SessionProjectionProtocolError(`Retained session event type ${event.type} carried contradictory subagent actor and payload identity.`);
|
|
34706
34780
|
return {
|
|
34707
34781
|
...event.actor,
|
|
@@ -34723,14 +34797,6 @@ function childActivityIdentity(event) {
|
|
|
34723
34797
|
}
|
|
34724
34798
|
return;
|
|
34725
34799
|
}
|
|
34726
|
-
function subagentLifecycleIdentityMatches({ actor, payload }) {
|
|
34727
|
-
return actor.actorId === payload.actorId && actor.subagentId === payload.subagentId && actor.parentActorId === payload.parentActorId && actor.parentToolCallId === payload.parentToolCallId && subagentOriginsMatch(actor.origin, payload.origin);
|
|
34728
|
-
}
|
|
34729
|
-
function subagentOriginsMatch(left, right) {
|
|
34730
|
-
if (left.type === "tool_call")
|
|
34731
|
-
return right.type === "tool_call" && left.toolCallId === right.toolCallId;
|
|
34732
|
-
return right.type === "provider_task" && left.taskId === right.taskId;
|
|
34733
|
-
}
|
|
34734
34800
|
function recordAgentLineageEvent({
|
|
34735
34801
|
state,
|
|
34736
34802
|
event,
|
|
@@ -34746,7 +34812,7 @@ function recordAgentLineageEvent({
|
|
|
34746
34812
|
return state;
|
|
34747
34813
|
throw error93;
|
|
34748
34814
|
}
|
|
34749
|
-
const runtimeBase =
|
|
34815
|
+
const runtimeBase = agentRuntimeIdentityKey(parsed);
|
|
34750
34816
|
let childLineage = state.childLineage;
|
|
34751
34817
|
if (parsed.type === "agent.session.started" || parsed.type === "agent.session.ended") {
|
|
34752
34818
|
const boundaryKey = `${runtimeBase}:${lengthPrefixed(parsed.eventId)}`;
|
|
@@ -34805,7 +34871,7 @@ function recordAgentLineageEvent({
|
|
|
34805
34871
|
return stampResolvedAttribution({ state: nextState, retainedEventId, fact, owner: resolution.owner });
|
|
34806
34872
|
}
|
|
34807
34873
|
function resolveBodyFactAgainstOwners(owners, fact) {
|
|
34808
|
-
const candidates = owners.filter((owner) => owner.runtimeScope === fact.runtimeScope &&
|
|
34874
|
+
const candidates = owners.filter((owner) => owner.runtimeScope === fact.runtimeScope && agentSubagentIdentitiesEqual(owner.identity, fact.identity));
|
|
34809
34875
|
const turnCandidates = candidates.filter((owner) => owner.childTurnIds.has(fact.turnId));
|
|
34810
34876
|
if (turnCandidates.length === 1)
|
|
34811
34877
|
return { status: "known", owner: turnCandidates[0] };
|
|
@@ -34837,9 +34903,6 @@ function stampResolvedAttribution({ state, retainedEventId, fact, owner }) {
|
|
|
34837
34903
|
}
|
|
34838
34904
|
return state;
|
|
34839
34905
|
}
|
|
34840
|
-
function lineageRuntimeBase(event) {
|
|
34841
|
-
return `${lengthPrefixed(event.sessionId)}:${lengthPrefixed(event.providerSessionId)}`;
|
|
34842
|
-
}
|
|
34843
34906
|
function lineageRuntimeScope({ runtimeBase, epoch }) {
|
|
34844
34907
|
return `${runtimeBase}:${epoch}`;
|
|
34845
34908
|
}
|
|
@@ -34852,9 +34915,6 @@ function isChildLineageFact(fact) {
|
|
|
34852
34915
|
function isSubagentLifecycleType(type) {
|
|
34853
34916
|
return type === "agent.subagent.started" || type === "agent.subagent.progress" || type === "agent.subagent.ended";
|
|
34854
34917
|
}
|
|
34855
|
-
function childIdentityMatches(left, right) {
|
|
34856
|
-
return left.actorId === right.actorId && left.subagentId === right.subagentId && left.parentActorId === right.parentActorId && left.parentToolCallId === right.parentToolCallId && subagentOriginsMatch(left.origin, right.origin);
|
|
34857
|
-
}
|
|
34858
34918
|
function childIdentityCanAnchor(identity) {
|
|
34859
34919
|
return identity.actorId !== identity.parentActorId && (identity.origin.type !== "tool_call" || identity.parentToolCallId === undefined || identity.parentToolCallId === identity.origin.toolCallId);
|
|
34860
34920
|
}
|
|
@@ -34888,9 +34948,9 @@ function reconcileChildLineage(state) {
|
|
|
34888
34948
|
if (parent && ownerHasActorAncestor(parent, fact.identity.actorId))
|
|
34889
34949
|
return;
|
|
34890
34950
|
const samePlacement = owners.filter((owner2) => owner2.runtimeScope === fact.runtimeScope && owner2.owningMainTurnId === owningMainTurnId && owner2.parent === parent && owner2.identity.actorId === fact.identity.actorId && owner2.identity.subagentId === fact.identity.subagentId);
|
|
34891
|
-
if (samePlacement.some((owner2) => !
|
|
34951
|
+
if (samePlacement.some((owner2) => !agentSubagentIdentitiesEqual(owner2.identity, fact.identity)))
|
|
34892
34952
|
return;
|
|
34893
|
-
const existing = samePlacement.find((owner2) =>
|
|
34953
|
+
const existing = samePlacement.find((owner2) => agentSubagentIdentitiesEqual(owner2.identity, fact.identity));
|
|
34894
34954
|
if (existing)
|
|
34895
34955
|
return existing;
|
|
34896
34956
|
const owner = {
|
|
@@ -34924,7 +34984,7 @@ function reconcileChildLineage(state) {
|
|
|
34924
34984
|
const toolTurn = mainTurnForToolOrigin(fact);
|
|
34925
34985
|
if (toolTurn === undefined)
|
|
34926
34986
|
continue;
|
|
34927
|
-
const owner = owners.find((candidate) => candidate.runtimeScope === fact.runtimeScope && candidate.parent === null && candidate.owningMainTurnId === toolTurn &&
|
|
34987
|
+
const owner = owners.find((candidate) => candidate.runtimeScope === fact.runtimeScope && candidate.parent === null && candidate.owningMainTurnId === toolTurn && agentSubagentIdentitiesEqual(candidate.identity, fact.identity)) ?? createOwner({ fact, owningMainTurnId: toolTurn, parent: null });
|
|
34928
34988
|
if (owner) {
|
|
34929
34989
|
ownerByFactOrder.set(fact.order, owner);
|
|
34930
34990
|
owner.childTurnIds.add(fact.turnId);
|
|
@@ -34937,7 +34997,7 @@ function reconcileChildLineage(state) {
|
|
|
34937
34997
|
for (const fact of childFacts) {
|
|
34938
34998
|
if (ownerByFactOrder.has(fact.order))
|
|
34939
34999
|
continue;
|
|
34940
|
-
const candidates = owners.filter((owner2) => owner2.runtimeScope === fact.runtimeScope &&
|
|
35000
|
+
const candidates = owners.filter((owner2) => owner2.runtimeScope === fact.runtimeScope && agentSubagentIdentitiesEqual(owner2.identity, fact.identity));
|
|
34941
35001
|
const turnCandidates = candidates.filter((owner2) => owner2.childTurnIds.has(fact.turnId));
|
|
34942
35002
|
const owner = turnCandidates.length === 1 ? turnCandidates[0] : candidates.length === 1 ? candidates[0] : undefined;
|
|
34943
35003
|
if (!owner || fact.eventType === "agent.subagent.started")
|
|
@@ -35013,12 +35073,16 @@ function ownerPath(owner) {
|
|
|
35013
35073
|
return path;
|
|
35014
35074
|
}
|
|
35015
35075
|
function childAttributionEqual(left, right) {
|
|
35016
|
-
if (left
|
|
35076
|
+
if (left === right)
|
|
35077
|
+
return true;
|
|
35078
|
+
if (!left || !right)
|
|
35079
|
+
return false;
|
|
35080
|
+
if (left.status !== right.status || left.activityTitle !== right.activityTitle || left.identity.name !== right.identity.name || !agentSubagentIdentitiesEqual(left.identity, right.identity)) {
|
|
35017
35081
|
return false;
|
|
35018
35082
|
}
|
|
35019
35083
|
if (left.status === "unresolved" || right.status === "unresolved")
|
|
35020
35084
|
return true;
|
|
35021
|
-
return left.ownerKey === right.ownerKey && left.owningMainTurnId === right.owningMainTurnId && left.path.length === right.path.length && left.path.every((identity, index) =>
|
|
35085
|
+
return left.ownerKey === right.ownerKey && left.owningMainTurnId === right.owningMainTurnId && left.path.length === right.path.length && left.path.every((identity, index) => identity.name === right.path[index].name && agentSubagentIdentitiesEqual(identity, right.path[index]));
|
|
35022
35086
|
}
|
|
35023
35087
|
function terminalSafeSingleLine(value) {
|
|
35024
35088
|
return stripAnsi(value).replace(/\s+/gu, " ").trim();
|
|
@@ -35251,6 +35315,7 @@ function createRemoteSessionController(dependencies) {
|
|
|
35251
35315
|
let stopped = false;
|
|
35252
35316
|
let state;
|
|
35253
35317
|
let cachedLastRetainedEventId;
|
|
35318
|
+
let cacheUnavailable = false;
|
|
35254
35319
|
let reasoningPreviewState = initialReasoningPreviewState();
|
|
35255
35320
|
let reasoningConnectionGeneration = 0;
|
|
35256
35321
|
let reasoningHistorySequenceFloor = -1;
|
|
@@ -35259,7 +35324,10 @@ function createRemoteSessionController(dependencies) {
|
|
|
35259
35324
|
ready = new Promise((resolve) => {
|
|
35260
35325
|
resolveReady = resolve;
|
|
35261
35326
|
});
|
|
35262
|
-
const cache = await readSessionCache(cachePath)
|
|
35327
|
+
const cache = await readSessionCache(cachePath).catch((error93) => {
|
|
35328
|
+
handleCacheError(error93);
|
|
35329
|
+
return null;
|
|
35330
|
+
});
|
|
35263
35331
|
cachedLastRetainedEventId = input.mode === "live" ? input.lastRetainedEventId ?? cache?.lastRetainedEventId : undefined;
|
|
35264
35332
|
state = createSessionViewState({
|
|
35265
35333
|
detail: input.detail,
|
|
@@ -35486,6 +35554,8 @@ function createRemoteSessionController(dependencies) {
|
|
|
35486
35554
|
};
|
|
35487
35555
|
}
|
|
35488
35556
|
async function writeCache() {
|
|
35557
|
+
if (cacheUnavailable)
|
|
35558
|
+
return;
|
|
35489
35559
|
const currentState = getState();
|
|
35490
35560
|
const cache = {
|
|
35491
35561
|
version: 1,
|
|
@@ -35495,7 +35565,13 @@ function createRemoteSessionController(dependencies) {
|
|
|
35495
35565
|
...currentState.activeMessageId ? { activeMessageId: currentState.activeMessageId } : {},
|
|
35496
35566
|
updatedAt: new Date().toISOString()
|
|
35497
35567
|
};
|
|
35498
|
-
await writeSessionCache({ path: cachePath, cache });
|
|
35568
|
+
await writeSessionCache({ path: cachePath, cache }).catch(handleCacheError);
|
|
35569
|
+
}
|
|
35570
|
+
function handleCacheError(error93) {
|
|
35571
|
+
if (!dependencies.onCacheError)
|
|
35572
|
+
throw error93;
|
|
35573
|
+
cacheUnavailable = true;
|
|
35574
|
+
dependencies.onCacheError(error93);
|
|
35499
35575
|
}
|
|
35500
35576
|
function publishState(frame) {
|
|
35501
35577
|
const update = { state: getState(), ...frame ? { frame } : {} };
|
|
@@ -37990,6 +38066,7 @@ var composerSlashCommands = [
|
|
|
37990
38066
|
{ value: "/sessions", description: "Back to the session list" },
|
|
37991
38067
|
{ value: "/complete", description: "Finish this session" },
|
|
37992
38068
|
{ value: "/cancel", description: "Cancel this session" },
|
|
38069
|
+
{ value: "/compact", description: "Compact main-thread context" },
|
|
37993
38070
|
{ value: "/new", description: "Start a new session" },
|
|
37994
38071
|
{ value: "/logout", description: "Sign out of Remy" },
|
|
37995
38072
|
{ value: "/help", description: "Show what you can do here" },
|
|
@@ -38001,6 +38078,7 @@ async function createSessionTui({
|
|
|
38001
38078
|
controller,
|
|
38002
38079
|
submitMessage,
|
|
38003
38080
|
requestInterrupt,
|
|
38081
|
+
requestCompact,
|
|
38004
38082
|
requestComplete,
|
|
38005
38083
|
requestCancel,
|
|
38006
38084
|
repositoryLabel,
|
|
@@ -38242,6 +38320,7 @@ async function createSessionTui({
|
|
|
38242
38320
|
let admittedSubmissions = [];
|
|
38243
38321
|
let stopState = { kind: "idle" };
|
|
38244
38322
|
let lifecycleRequestState = { kind: "idle" };
|
|
38323
|
+
let contextCompactionRequestState = { kind: "idle" };
|
|
38245
38324
|
let helpVisible = false;
|
|
38246
38325
|
let logoutConfirmationOpen = false;
|
|
38247
38326
|
let latestState = controller.getState();
|
|
@@ -38592,6 +38671,12 @@ async function createSessionTui({
|
|
|
38592
38671
|
handleLifecycleRequest("cancel");
|
|
38593
38672
|
return true;
|
|
38594
38673
|
}
|
|
38674
|
+
if (command === "/compact") {
|
|
38675
|
+
composer.setText("");
|
|
38676
|
+
composerDraft = { ...composerDraft, text: "" };
|
|
38677
|
+
await handleCompactionRequest();
|
|
38678
|
+
return true;
|
|
38679
|
+
}
|
|
38595
38680
|
if (command === "/logout") {
|
|
38596
38681
|
composer.setText("");
|
|
38597
38682
|
composerDraft = { ...composerDraft, text: "" };
|
|
@@ -38679,6 +38764,39 @@ async function createSessionTui({
|
|
|
38679
38764
|
}
|
|
38680
38765
|
render();
|
|
38681
38766
|
}
|
|
38767
|
+
async function handleCompactionRequest() {
|
|
38768
|
+
if (contextCompactionRequestState.kind === "requesting")
|
|
38769
|
+
return;
|
|
38770
|
+
if (latestState.aggregateStatus !== "open") {
|
|
38771
|
+
composerFeedback = "This session is already terminal.";
|
|
38772
|
+
render();
|
|
38773
|
+
return;
|
|
38774
|
+
}
|
|
38775
|
+
const idempotencyKey = contextCompactionRequestState.kind === "delivery-unknown" ? contextCompactionRequestState.idempotencyKey : crypto.randomUUID();
|
|
38776
|
+
contextCompactionRequestState = { kind: "requesting", idempotencyKey };
|
|
38777
|
+
composerFeedback = "Requesting context compaction\u2026";
|
|
38778
|
+
render();
|
|
38779
|
+
try {
|
|
38780
|
+
await requestCompact({ idempotencyKey });
|
|
38781
|
+
if (!destroyed) {
|
|
38782
|
+
contextCompactionRequestState = { kind: "admitted" };
|
|
38783
|
+
composerFeedback = "Context compaction request admitted. Result will appear in the timeline.";
|
|
38784
|
+
}
|
|
38785
|
+
} catch (error93) {
|
|
38786
|
+
if (!destroyed) {
|
|
38787
|
+
const message = error93 instanceof Error ? error93.message : String(error93);
|
|
38788
|
+
if (isKnownClientRejection(error93)) {
|
|
38789
|
+
contextCompactionRequestState = { kind: "idle" };
|
|
38790
|
+
composerFeedback = `Could not request context compaction: ${message}`;
|
|
38791
|
+
} else {
|
|
38792
|
+
contextCompactionRequestState = { kind: "delivery-unknown", idempotencyKey };
|
|
38793
|
+
composerFeedback = `Context compaction admission is unknown: ${message}. Run /compact again to retry the same request.`;
|
|
38794
|
+
}
|
|
38795
|
+
}
|
|
38796
|
+
}
|
|
38797
|
+
if (!destroyed)
|
|
38798
|
+
render();
|
|
38799
|
+
}
|
|
38682
38800
|
async function handleLifecycleRequest(operation) {
|
|
38683
38801
|
if (lifecycleRequestState.kind === "pending")
|
|
38684
38802
|
return;
|
|
@@ -38805,6 +38923,7 @@ var helpEntries = [
|
|
|
38805
38923
|
{ group: "command", token: "/sessions", description: "back to the session list" },
|
|
38806
38924
|
{ group: "command", token: "/complete", description: "finish this session" },
|
|
38807
38925
|
{ group: "command", token: "/cancel", description: "cancel this session" },
|
|
38926
|
+
{ group: "command", token: "/compact", description: "compact main-thread context" },
|
|
38808
38927
|
{ group: "command", token: "/logout", description: "sign out of Remy" },
|
|
38809
38928
|
{ group: "command", token: "/exit", description: "leave Remy" },
|
|
38810
38929
|
{ group: "key", token: "esc", description: "stop Remy\u2019s current turn" },
|
|
@@ -39022,19 +39141,7 @@ function activityGlyph({ kind, inFlight }) {
|
|
|
39022
39141
|
return { glyph: "\u2713", color: PALETTE.dimText };
|
|
39023
39142
|
}
|
|
39024
39143
|
function activityCardsHaveEqualDisclosure(left, right) {
|
|
39025
|
-
return left.kind === right.kind && left.title === right.title && left.summary === right.summary && left.detail === right.detail && left.detailFormat === right.detailFormat &&
|
|
39026
|
-
}
|
|
39027
|
-
function canonicalValuesEqual(left, right) {
|
|
39028
|
-
if (Object.is(left, right))
|
|
39029
|
-
return true;
|
|
39030
|
-
if (Array.isArray(left) || Array.isArray(right)) {
|
|
39031
|
-
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((value, index) => canonicalValuesEqual(value, right[index]));
|
|
39032
|
-
}
|
|
39033
|
-
if (typeof left !== "object" || left === null || typeof right !== "object" || right === null)
|
|
39034
|
-
return false;
|
|
39035
|
-
const leftEntries = Object.entries(left);
|
|
39036
|
-
const rightEntries = Object.entries(right);
|
|
39037
|
-
return leftEntries.length === rightEntries.length && leftEntries.every(([key, value], index) => rightEntries[index]?.[0] === key && canonicalValuesEqual(value, rightEntries[index]?.[1]));
|
|
39144
|
+
return left.kind === right.kind && left.title === right.title && left.summary === right.summary && left.detail === right.detail && left.detailFormat === right.detailFormat && childAttributionEqual(left.attribution, right.attribution);
|
|
39038
39145
|
}
|
|
39039
39146
|
function renderActivityGroup({ items, activityExpanded }) {
|
|
39040
39147
|
if (items.length === 0)
|
|
@@ -39235,6 +39342,12 @@ function renderComposerStatus({ admittedSubmissions }) {
|
|
|
39235
39342
|
|
|
39236
39343
|
`);
|
|
39237
39344
|
}
|
|
39345
|
+
function isKnownClientRejection(error93) {
|
|
39346
|
+
if (typeof error93 !== "object" || error93 === null || !("status" in error93))
|
|
39347
|
+
return false;
|
|
39348
|
+
const status = error93.status;
|
|
39349
|
+
return typeof status === "number" && status >= 400 && status < 500;
|
|
39350
|
+
}
|
|
39238
39351
|
async function createDefaultRenderer3() {
|
|
39239
39352
|
return await createRemyRenderer();
|
|
39240
39353
|
}
|
|
@@ -39495,7 +39608,7 @@ var compactMarkRows = 9;
|
|
|
39495
39608
|
var compactMinWidth = 48;
|
|
39496
39609
|
var compactMinHeight = 20;
|
|
39497
39610
|
var markBrightnessGain = 4.2;
|
|
39498
|
-
var remyCliVersion = "1.
|
|
39611
|
+
var remyCliVersion = "1.17.0";
|
|
39499
39612
|
async function showRemySplash({
|
|
39500
39613
|
createRenderer = createRemyRenderer,
|
|
39501
39614
|
durationMs = splashDurationMs,
|
|
@@ -39868,7 +39981,7 @@ async function dispatchCliCommandWithShutdown({
|
|
|
39868
39981
|
});
|
|
39869
39982
|
}
|
|
39870
39983
|
if (command.name === "session")
|
|
39871
|
-
return await attachSession({ dependencies, sessionId: command.sessionId, noTui: command.noTui, json: command.json });
|
|
39984
|
+
return await attachSession({ dependencies, sessionId: command.sessionId, noTui: command.noTui, json: command.json, prompt: command.prompt });
|
|
39872
39985
|
return await createNewSession({ dependencies, command });
|
|
39873
39986
|
}
|
|
39874
39987
|
function createCliShutdown({ abortSignal }) {
|
|
@@ -40775,12 +40888,30 @@ async function attachSession({
|
|
|
40775
40888
|
dependencies,
|
|
40776
40889
|
sessionId,
|
|
40777
40890
|
noTui,
|
|
40778
|
-
json: json3
|
|
40891
|
+
json: json3,
|
|
40892
|
+
prompt
|
|
40779
40893
|
}) {
|
|
40780
40894
|
const operations = await createSessionOperations(dependencies);
|
|
40781
40895
|
const detail = await operations.getSession({ client: operations.client, sessionId });
|
|
40782
40896
|
const repositories = detail.repositories.map((repository) => ({ id: repository.id, fullName: repository.full_name }));
|
|
40783
40897
|
const cache = await (dependencies.readSessionCache ?? readSessionCache)(resolveSessionCachePathForCommand({ dependencies, sessionId }));
|
|
40898
|
+
let activeMessageId = cache?.activeMessageId;
|
|
40899
|
+
let cacheWarningReported = false;
|
|
40900
|
+
const onCacheError = prompt === undefined ? undefined : () => {
|
|
40901
|
+
if (cacheWarningReported)
|
|
40902
|
+
return;
|
|
40903
|
+
cacheWarningReported = true;
|
|
40904
|
+
dependencies.output.writeStderr(`Local session cache is unavailable; continuing to observe the accepted follow-up. Do not resubmit the prompt.
|
|
40905
|
+
`);
|
|
40906
|
+
};
|
|
40907
|
+
if (prompt !== undefined) {
|
|
40908
|
+
throwIfAborted2(dependencies.abortSignal);
|
|
40909
|
+
const appended = await operations.appendSessionMessage({
|
|
40910
|
+
client: operations.client,
|
|
40911
|
+
input: { sessionId, text: prompt, fileIds: [], mode: "steer", idempotencyKey: randomUUID5() }
|
|
40912
|
+
});
|
|
40913
|
+
activeMessageId = appended.message.id;
|
|
40914
|
+
}
|
|
40784
40915
|
await (dependencies.writeSessionCache ?? writeSessionCache)({
|
|
40785
40916
|
path: resolveSessionCachePathForCommand({ dependencies, sessionId }),
|
|
40786
40917
|
cache: {
|
|
@@ -40788,20 +40919,25 @@ async function attachSession({
|
|
|
40788
40919
|
sessionId,
|
|
40789
40920
|
repositories,
|
|
40790
40921
|
...cache?.lastRetainedEventId ? { lastRetainedEventId: cache.lastRetainedEventId } : {},
|
|
40791
|
-
...
|
|
40922
|
+
...activeMessageId ? { activeMessageId } : {},
|
|
40792
40923
|
updatedAt: new Date().toISOString()
|
|
40793
40924
|
}
|
|
40925
|
+
}).catch((error93) => {
|
|
40926
|
+
if (!onCacheError)
|
|
40927
|
+
throw error93;
|
|
40928
|
+
onCacheError();
|
|
40794
40929
|
});
|
|
40795
40930
|
return await runAttachedSession({
|
|
40796
40931
|
dependencies,
|
|
40797
40932
|
operations,
|
|
40798
40933
|
sessionId,
|
|
40799
40934
|
repositories,
|
|
40800
|
-
activeMessageId
|
|
40935
|
+
activeMessageId,
|
|
40801
40936
|
start: { mode: "cold-resume", detail },
|
|
40802
40937
|
noTui,
|
|
40803
40938
|
json: json3,
|
|
40804
|
-
emitCreated: false
|
|
40939
|
+
emitCreated: false,
|
|
40940
|
+
onCacheError
|
|
40805
40941
|
});
|
|
40806
40942
|
}
|
|
40807
40943
|
async function runAttachedSession({
|
|
@@ -40813,7 +40949,8 @@ async function runAttachedSession({
|
|
|
40813
40949
|
start,
|
|
40814
40950
|
noTui,
|
|
40815
40951
|
json: json3,
|
|
40816
|
-
emitCreated
|
|
40952
|
+
emitCreated,
|
|
40953
|
+
onCacheError
|
|
40817
40954
|
}) {
|
|
40818
40955
|
if (dependencies.abortSignal?.aborted)
|
|
40819
40956
|
throw dependencies.abortSignal.reason ?? new Error("interrupted");
|
|
@@ -40823,6 +40960,7 @@ async function runAttachedSession({
|
|
|
40823
40960
|
repositories,
|
|
40824
40961
|
...activeMessageId ? { activeMessageId } : {},
|
|
40825
40962
|
environment: dependencies.environment,
|
|
40963
|
+
onCacheError,
|
|
40826
40964
|
getSession: async ({ sessionId: id }) => await operations.getSession({ client: operations.client, sessionId: id }),
|
|
40827
40965
|
listSessionEvents: async ({ sessionId: id, limit, after, signal }) => await operations.listSessionEvents({ client: operations.client, sessionId: id, limit, after, signal }),
|
|
40828
40966
|
openEventStream: ({ sessionId: id, lastRetainedEventId, signal, onSynchronized }) => operations.streamSessionEvents({ client: operations.client, sessionId: id, lastRetainedEventId, signal, onSynchronized })
|
|
@@ -40898,6 +41036,9 @@ async function runAttachedSession({
|
|
|
40898
41036
|
requestInterrupt: async ({ idempotencyKey }) => {
|
|
40899
41037
|
await operations.interruptSession({ client: operations.client, sessionId, idempotencyKey });
|
|
40900
41038
|
},
|
|
41039
|
+
requestCompact: async ({ idempotencyKey }) => {
|
|
41040
|
+
await operations.compactSessionContext({ client: operations.client, sessionId, idempotencyKey });
|
|
41041
|
+
},
|
|
40901
41042
|
requestComplete: async () => {
|
|
40902
41043
|
const detail = await operations.completeSession({ client: operations.client, sessionId });
|
|
40903
41044
|
controller.updateDetail(detail);
|
|
@@ -41024,6 +41165,7 @@ async function createSessionOperations(dependencies, { onAuthenticated } = {}) {
|
|
|
41024
41165
|
appendSessionMessage: dependencies.appendSessionMessage ?? appendSessionMessage,
|
|
41025
41166
|
cancelSession: dependencies.cancelSession ?? cancelSession,
|
|
41026
41167
|
completeSession: dependencies.completeSession ?? completeSession,
|
|
41168
|
+
compactSessionContext: dependencies.compactSessionContext ?? compactSessionContext,
|
|
41027
41169
|
interruptSession: dependencies.interruptSession ?? interruptSession,
|
|
41028
41170
|
getSession: dependencies.getSession ?? getSession,
|
|
41029
41171
|
listSessionEvents: dependencies.listSessionEvents ?? listSessionEvents,
|
|
@@ -41044,6 +41186,7 @@ async function createSessionOperations(dependencies, { onAuthenticated } = {}) {
|
|
|
41044
41186
|
appendSessionMessage: dependencies.appendSessionMessage ?? appendSessionMessage,
|
|
41045
41187
|
cancelSession: dependencies.cancelSession ?? cancelSession,
|
|
41046
41188
|
completeSession: dependencies.completeSession ?? completeSession,
|
|
41189
|
+
compactSessionContext: dependencies.compactSessionContext ?? compactSessionContext,
|
|
41047
41190
|
interruptSession: dependencies.interruptSession ?? interruptSession,
|
|
41048
41191
|
getSession: dependencies.getSession ?? getSession,
|
|
41049
41192
|
listSessionEvents: dependencies.listSessionEvents ?? listSessionEvents,
|
|
@@ -41200,10 +41343,15 @@ Options:
|
|
|
41200
41343
|
`;
|
|
41201
41344
|
}
|
|
41202
41345
|
if (topic === "session") {
|
|
41203
|
-
return `Usage: remy --session <session-id> [options]
|
|
41346
|
+
return `Usage: remy --session <session-id> [options] [prompt]
|
|
41204
41347
|
|
|
41205
41348
|
Attach to an existing remote session. An interactive terminal opens the session view; --no-tui streams output instead.
|
|
41206
41349
|
|
|
41350
|
+
Arguments:
|
|
41351
|
+
prompt Submit a follow-up as Steer before attaching
|
|
41352
|
+
|
|
41353
|
+
With a prompt, JSON output waits for that message's turn result. Use -- before a prompt beginning with --.
|
|
41354
|
+
|
|
41207
41355
|
Options:
|
|
41208
41356
|
--no-tui Do not open the interactive terminal view
|
|
41209
41357
|
--json Write session updates as JSON
|
|
@@ -41235,8 +41383,8 @@ Usage:
|
|
|
41235
41383
|
Commands:
|
|
41236
41384
|
remy Open interactive dashboard
|
|
41237
41385
|
remy dashboard Open interactive dashboard
|
|
41238
|
-
remy --session <session-id> [--no-tui] [--json]
|
|
41239
|
-
Attach to a session
|
|
41386
|
+
remy --session <session-id> [--no-tui] [--json] [prompt]
|
|
41387
|
+
Attach to a session, optionally submitting a follow-up
|
|
41240
41388
|
remy new [--repository <owner/name> ... --installation <id> --model <name> --reasoning-effort <low|medium|high|xhigh> --attach <path> ... --no-tui --json] <prompt>
|
|
41241
41389
|
Create a session
|
|
41242
41390
|
remy login [--env production|staging] [--api-url <url> --auth-api-url <url> --requester-application-id <uuid> --target-application-id <uuid>]
|
|
@@ -41268,14 +41416,32 @@ function parseSessionAttach(argv) {
|
|
|
41268
41416
|
const sessionId = argv[0];
|
|
41269
41417
|
if (!sessionId || sessionId.startsWith("--"))
|
|
41270
41418
|
throw new Error("--session requires a session ID.");
|
|
41271
|
-
|
|
41272
|
-
|
|
41273
|
-
|
|
41274
|
-
|
|
41275
|
-
|
|
41276
|
-
|
|
41419
|
+
let noTui = false;
|
|
41420
|
+
let json3 = false;
|
|
41421
|
+
let prompt;
|
|
41422
|
+
let positionalOnly = false;
|
|
41423
|
+
for (const token of argv.slice(1)) {
|
|
41424
|
+
if (!positionalOnly && token === "--") {
|
|
41425
|
+
positionalOnly = true;
|
|
41426
|
+
continue;
|
|
41427
|
+
}
|
|
41428
|
+
if (!positionalOnly && token === "--no-tui") {
|
|
41429
|
+
noTui = true;
|
|
41430
|
+
continue;
|
|
41431
|
+
}
|
|
41432
|
+
if (!positionalOnly && token === "--json") {
|
|
41433
|
+
json3 = true;
|
|
41434
|
+
continue;
|
|
41435
|
+
}
|
|
41436
|
+
if (!positionalOnly && token.startsWith("--"))
|
|
41437
|
+
throw new Error(`Unknown --session flag ${token}.`);
|
|
41438
|
+
if (prompt !== undefined)
|
|
41439
|
+
throw new Error("--session accepts one prompt. Quote the full prompt as a single argument.");
|
|
41440
|
+
if (!token.trim())
|
|
41441
|
+
throw new Error("A follow-up prompt must not be empty.");
|
|
41442
|
+
prompt = token;
|
|
41277
41443
|
}
|
|
41278
|
-
return { name: "session", sessionId, noTui:
|
|
41444
|
+
return { name: "session", sessionId, noTui, json: json3, ...prompt === undefined ? {} : { prompt } };
|
|
41279
41445
|
}
|
|
41280
41446
|
function parseNewCommand(argv) {
|
|
41281
41447
|
const repositories = [];
|