@meistrari/remy-cli 1.16.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 +12 -1
- package/dist/remy.js +79 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -102,6 +102,14 @@ The branch-suggestion flow belongs to the interactive new-session wizard (`remy`
|
|
|
102
102
|
remy --session <session-id>
|
|
103
103
|
```
|
|
104
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
|
+
|
|
105
113
|
### Automate a session
|
|
106
114
|
|
|
107
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.
|
|
@@ -111,8 +119,11 @@ Opaque session and message metadata returned by the API is accepted for compatib
|
|
|
111
119
|
```bash
|
|
112
120
|
remy new --no-tui --repository owner/repository "Add a health check endpoint"
|
|
113
121
|
remy --session <session-id> --json
|
|
122
|
+
remy --session <session-id> --no-tui "Add regression coverage for that fix"
|
|
114
123
|
```
|
|
115
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
|
+
|
|
116
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`.
|
|
117
128
|
|
|
118
129
|
```json
|
|
@@ -154,7 +165,7 @@ remy logout [--api-url <url>]
|
|
|
154
165
|
remy whoami
|
|
155
166
|
remy dashboard
|
|
156
167
|
remy new [--repository <owner/name> ... --installation <id> --model <name> --reasoning-effort <low|medium|high|xhigh> --attach <path> ... --no-tui --json] <prompt>
|
|
157
|
-
remy --session <session-id> [--no-tui] [--json]
|
|
168
|
+
remy --session <session-id> [--no-tui] [--json] [prompt]
|
|
158
169
|
```
|
|
159
170
|
|
|
160
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
|
@@ -35315,6 +35315,7 @@ function createRemoteSessionController(dependencies) {
|
|
|
35315
35315
|
let stopped = false;
|
|
35316
35316
|
let state;
|
|
35317
35317
|
let cachedLastRetainedEventId;
|
|
35318
|
+
let cacheUnavailable = false;
|
|
35318
35319
|
let reasoningPreviewState = initialReasoningPreviewState();
|
|
35319
35320
|
let reasoningConnectionGeneration = 0;
|
|
35320
35321
|
let reasoningHistorySequenceFloor = -1;
|
|
@@ -35323,7 +35324,10 @@ function createRemoteSessionController(dependencies) {
|
|
|
35323
35324
|
ready = new Promise((resolve) => {
|
|
35324
35325
|
resolveReady = resolve;
|
|
35325
35326
|
});
|
|
35326
|
-
const cache = await readSessionCache(cachePath)
|
|
35327
|
+
const cache = await readSessionCache(cachePath).catch((error93) => {
|
|
35328
|
+
handleCacheError(error93);
|
|
35329
|
+
return null;
|
|
35330
|
+
});
|
|
35327
35331
|
cachedLastRetainedEventId = input.mode === "live" ? input.lastRetainedEventId ?? cache?.lastRetainedEventId : undefined;
|
|
35328
35332
|
state = createSessionViewState({
|
|
35329
35333
|
detail: input.detail,
|
|
@@ -35550,6 +35554,8 @@ function createRemoteSessionController(dependencies) {
|
|
|
35550
35554
|
};
|
|
35551
35555
|
}
|
|
35552
35556
|
async function writeCache() {
|
|
35557
|
+
if (cacheUnavailable)
|
|
35558
|
+
return;
|
|
35553
35559
|
const currentState = getState();
|
|
35554
35560
|
const cache = {
|
|
35555
35561
|
version: 1,
|
|
@@ -35559,7 +35565,13 @@ function createRemoteSessionController(dependencies) {
|
|
|
35559
35565
|
...currentState.activeMessageId ? { activeMessageId: currentState.activeMessageId } : {},
|
|
35560
35566
|
updatedAt: new Date().toISOString()
|
|
35561
35567
|
};
|
|
35562
|
-
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);
|
|
35563
35575
|
}
|
|
35564
35576
|
function publishState(frame) {
|
|
35565
35577
|
const update = { state: getState(), ...frame ? { frame } : {} };
|
|
@@ -39596,7 +39608,7 @@ var compactMarkRows = 9;
|
|
|
39596
39608
|
var compactMinWidth = 48;
|
|
39597
39609
|
var compactMinHeight = 20;
|
|
39598
39610
|
var markBrightnessGain = 4.2;
|
|
39599
|
-
var remyCliVersion = "1.
|
|
39611
|
+
var remyCliVersion = "1.17.0";
|
|
39600
39612
|
async function showRemySplash({
|
|
39601
39613
|
createRenderer = createRemyRenderer,
|
|
39602
39614
|
durationMs = splashDurationMs,
|
|
@@ -39969,7 +39981,7 @@ async function dispatchCliCommandWithShutdown({
|
|
|
39969
39981
|
});
|
|
39970
39982
|
}
|
|
39971
39983
|
if (command.name === "session")
|
|
39972
|
-
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 });
|
|
39973
39985
|
return await createNewSession({ dependencies, command });
|
|
39974
39986
|
}
|
|
39975
39987
|
function createCliShutdown({ abortSignal }) {
|
|
@@ -40876,12 +40888,30 @@ async function attachSession({
|
|
|
40876
40888
|
dependencies,
|
|
40877
40889
|
sessionId,
|
|
40878
40890
|
noTui,
|
|
40879
|
-
json: json3
|
|
40891
|
+
json: json3,
|
|
40892
|
+
prompt
|
|
40880
40893
|
}) {
|
|
40881
40894
|
const operations = await createSessionOperations(dependencies);
|
|
40882
40895
|
const detail = await operations.getSession({ client: operations.client, sessionId });
|
|
40883
40896
|
const repositories = detail.repositories.map((repository) => ({ id: repository.id, fullName: repository.full_name }));
|
|
40884
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
|
+
}
|
|
40885
40915
|
await (dependencies.writeSessionCache ?? writeSessionCache)({
|
|
40886
40916
|
path: resolveSessionCachePathForCommand({ dependencies, sessionId }),
|
|
40887
40917
|
cache: {
|
|
@@ -40889,20 +40919,25 @@ async function attachSession({
|
|
|
40889
40919
|
sessionId,
|
|
40890
40920
|
repositories,
|
|
40891
40921
|
...cache?.lastRetainedEventId ? { lastRetainedEventId: cache.lastRetainedEventId } : {},
|
|
40892
|
-
...
|
|
40922
|
+
...activeMessageId ? { activeMessageId } : {},
|
|
40893
40923
|
updatedAt: new Date().toISOString()
|
|
40894
40924
|
}
|
|
40925
|
+
}).catch((error93) => {
|
|
40926
|
+
if (!onCacheError)
|
|
40927
|
+
throw error93;
|
|
40928
|
+
onCacheError();
|
|
40895
40929
|
});
|
|
40896
40930
|
return await runAttachedSession({
|
|
40897
40931
|
dependencies,
|
|
40898
40932
|
operations,
|
|
40899
40933
|
sessionId,
|
|
40900
40934
|
repositories,
|
|
40901
|
-
activeMessageId
|
|
40935
|
+
activeMessageId,
|
|
40902
40936
|
start: { mode: "cold-resume", detail },
|
|
40903
40937
|
noTui,
|
|
40904
40938
|
json: json3,
|
|
40905
|
-
emitCreated: false
|
|
40939
|
+
emitCreated: false,
|
|
40940
|
+
onCacheError
|
|
40906
40941
|
});
|
|
40907
40942
|
}
|
|
40908
40943
|
async function runAttachedSession({
|
|
@@ -40914,7 +40949,8 @@ async function runAttachedSession({
|
|
|
40914
40949
|
start,
|
|
40915
40950
|
noTui,
|
|
40916
40951
|
json: json3,
|
|
40917
|
-
emitCreated
|
|
40952
|
+
emitCreated,
|
|
40953
|
+
onCacheError
|
|
40918
40954
|
}) {
|
|
40919
40955
|
if (dependencies.abortSignal?.aborted)
|
|
40920
40956
|
throw dependencies.abortSignal.reason ?? new Error("interrupted");
|
|
@@ -40924,6 +40960,7 @@ async function runAttachedSession({
|
|
|
40924
40960
|
repositories,
|
|
40925
40961
|
...activeMessageId ? { activeMessageId } : {},
|
|
40926
40962
|
environment: dependencies.environment,
|
|
40963
|
+
onCacheError,
|
|
40927
40964
|
getSession: async ({ sessionId: id }) => await operations.getSession({ client: operations.client, sessionId: id }),
|
|
40928
40965
|
listSessionEvents: async ({ sessionId: id, limit, after, signal }) => await operations.listSessionEvents({ client: operations.client, sessionId: id, limit, after, signal }),
|
|
40929
40966
|
openEventStream: ({ sessionId: id, lastRetainedEventId, signal, onSynchronized }) => operations.streamSessionEvents({ client: operations.client, sessionId: id, lastRetainedEventId, signal, onSynchronized })
|
|
@@ -41306,10 +41343,15 @@ Options:
|
|
|
41306
41343
|
`;
|
|
41307
41344
|
}
|
|
41308
41345
|
if (topic === "session") {
|
|
41309
|
-
return `Usage: remy --session <session-id> [options]
|
|
41346
|
+
return `Usage: remy --session <session-id> [options] [prompt]
|
|
41310
41347
|
|
|
41311
41348
|
Attach to an existing remote session. An interactive terminal opens the session view; --no-tui streams output instead.
|
|
41312
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
|
+
|
|
41313
41355
|
Options:
|
|
41314
41356
|
--no-tui Do not open the interactive terminal view
|
|
41315
41357
|
--json Write session updates as JSON
|
|
@@ -41341,8 +41383,8 @@ Usage:
|
|
|
41341
41383
|
Commands:
|
|
41342
41384
|
remy Open interactive dashboard
|
|
41343
41385
|
remy dashboard Open interactive dashboard
|
|
41344
|
-
remy --session <session-id> [--no-tui] [--json]
|
|
41345
|
-
Attach to a session
|
|
41386
|
+
remy --session <session-id> [--no-tui] [--json] [prompt]
|
|
41387
|
+
Attach to a session, optionally submitting a follow-up
|
|
41346
41388
|
remy new [--repository <owner/name> ... --installation <id> --model <name> --reasoning-effort <low|medium|high|xhigh> --attach <path> ... --no-tui --json] <prompt>
|
|
41347
41389
|
Create a session
|
|
41348
41390
|
remy login [--env production|staging] [--api-url <url> --auth-api-url <url> --requester-application-id <uuid> --target-application-id <uuid>]
|
|
@@ -41374,14 +41416,32 @@ function parseSessionAttach(argv) {
|
|
|
41374
41416
|
const sessionId = argv[0];
|
|
41375
41417
|
if (!sessionId || sessionId.startsWith("--"))
|
|
41376
41418
|
throw new Error("--session requires a session ID.");
|
|
41377
|
-
|
|
41378
|
-
|
|
41379
|
-
|
|
41380
|
-
|
|
41381
|
-
|
|
41382
|
-
|
|
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;
|
|
41383
41443
|
}
|
|
41384
|
-
return { name: "session", sessionId, noTui:
|
|
41444
|
+
return { name: "session", sessionId, noTui, json: json3, ...prompt === undefined ? {} : { prompt } };
|
|
41385
41445
|
}
|
|
41386
41446
|
function parseNewCommand(argv) {
|
|
41387
41447
|
const repositories = [];
|