jeo-code 0.12.11 → 0.12.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/package.json +1 -1
- package/src/commands/launch.ts +3 -22
- package/src/messenger/activity.ts +13 -17
- package/src/messenger/discord.ts +16 -23
- package/src/messenger/gateway.ts +7 -8
- package/src/messenger/types.ts +2 -5
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
The README mirrors the latest 5 entries — regenerate with `bun run changelog:sync`.
|
|
9
9
|
|
|
10
|
+
## [0.12.12] - 2026-11-03
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Discord messenger progress** — show safe, throttled step and tool updates in a single request status message, retaining recent activity and marking completion, failure, or cancellation without exposing tool arguments or output.
|
|
14
|
+
|
|
10
15
|
## [0.12.10] - 2026-11-02
|
|
11
16
|
## [0.12.11] - 2026-11-02
|
|
12
17
|
|
package/README.ja.md
CHANGED
|
@@ -422,11 +422,11 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
|
|
|
422
422
|
## 変更履歴 (Changelog)
|
|
423
423
|
|
|
424
424
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
425
|
+
- **[0.12.12]** (2026-11-03)
|
|
425
426
|
- **[0.12.10]** (2026-11-02)
|
|
426
427
|
- **[0.12.11]** (2026-11-02)
|
|
427
428
|
- **[0.12.9]** (2026-11-02)
|
|
428
429
|
- **[0.12.7]** (2026-10-18) — Repair desktop screenshot vision feedback, macOS scrolling, complete drag gestures, and keyboard normalization.
|
|
429
|
-
- **[0.12.6]** (2026-10-17) — Preserve OpenAI subscription authentication behind configured proxies, isolate account catalogs, and give provider-specific recovery instructions while retaining Antigravity OAuth calls.
|
|
430
430
|
|
|
431
431
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
432
432
|
<!-- CHANGELOG:END -->
|
package/README.ko.md
CHANGED
|
@@ -477,11 +477,11 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
|
|
|
477
477
|
## 변경 이력 (Changelog)
|
|
478
478
|
|
|
479
479
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
480
|
+
- **[0.12.12]** (2026-11-03)
|
|
480
481
|
- **[0.12.10]** (2026-11-02)
|
|
481
482
|
- **[0.12.11]** (2026-11-02)
|
|
482
483
|
- **[0.12.9]** (2026-11-02)
|
|
483
484
|
- **[0.12.7]** (2026-10-18) — Repair desktop screenshot vision feedback, macOS scrolling, complete drag gestures, and keyboard normalization.
|
|
484
|
-
- **[0.12.6]** (2026-10-17) — Preserve OpenAI subscription authentication behind configured proxies, isolate account catalogs, and give provider-specific recovery instructions while retaining Antigravity OAuth calls.
|
|
485
485
|
|
|
486
486
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
487
487
|
<!-- CHANGELOG:END -->
|
package/README.md
CHANGED
|
@@ -466,11 +466,11 @@ Huge thanks to [gajae-code](https://github.com/Yeachan-Heo/gajae-code) for the i
|
|
|
466
466
|
## Changelog
|
|
467
467
|
|
|
468
468
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
469
|
+
- **[0.12.12]** (2026-11-03)
|
|
469
470
|
- **[0.12.10]** (2026-11-02)
|
|
470
471
|
- **[0.12.11]** (2026-11-02)
|
|
471
472
|
- **[0.12.9]** (2026-11-02)
|
|
472
473
|
- **[0.12.7]** (2026-10-18) — Repair desktop screenshot vision feedback, macOS scrolling, complete drag gestures, and keyboard normalization.
|
|
473
|
-
- **[0.12.6]** (2026-10-17) — Preserve OpenAI subscription authentication behind configured proxies, isolate account catalogs, and give provider-specific recovery instructions while retaining Antigravity OAuth calls.
|
|
474
474
|
|
|
475
475
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
476
476
|
<!-- CHANGELOG:END -->
|
package/README.zh.md
CHANGED
|
@@ -420,11 +420,11 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
|
|
|
420
420
|
## 更新日志 (Changelog)
|
|
421
421
|
|
|
422
422
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
423
|
+
- **[0.12.12]** (2026-11-03)
|
|
423
424
|
- **[0.12.10]** (2026-11-02)
|
|
424
425
|
- **[0.12.11]** (2026-11-02)
|
|
425
426
|
- **[0.12.9]** (2026-11-02)
|
|
426
427
|
- **[0.12.7]** (2026-10-18) — Repair desktop screenshot vision feedback, macOS scrolling, complete drag gestures, and keyboard normalization.
|
|
427
|
-
- **[0.12.6]** (2026-10-17) — Preserve OpenAI subscription authentication behind configured proxies, isolate account catalogs, and give provider-specific recovery instructions while retaining Antigravity OAuth calls.
|
|
428
428
|
|
|
429
429
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
430
430
|
<!-- CHANGELOG:END -->
|
package/package.json
CHANGED
package/src/commands/launch.ts
CHANGED
|
@@ -114,7 +114,7 @@ import type { ImageAttachment } from "../ai/types";
|
|
|
114
114
|
import { renderMarkdownTables } from "../tui/components/markdown-table";
|
|
115
115
|
|
|
116
116
|
import { stripMarkdown } from "../tui/components/markdown-text";
|
|
117
|
-
import {
|
|
117
|
+
import { createMessengerActivityEvents } from "../messenger/activity";
|
|
118
118
|
import { formatDuration, formatUsage } from "../tui/components/duration";
|
|
119
119
|
|
|
120
120
|
import { bashTool } from "../agent/tools";
|
|
@@ -1034,28 +1034,9 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
1034
1034
|
// `step N/M` display seed: the explicit --max-steps cap, else the dynamic budget's
|
|
1035
1035
|
// rolling base — the engine's onBudget event keeps the denominator honest as it grows.
|
|
1036
1036
|
const initialStepLimit = flags.maxSteps > 0 ? flags.maxSteps : initialDynamicStepLimit();
|
|
1037
|
-
//
|
|
1037
|
+
// Literal workers send progress without exposing tool arguments or output.
|
|
1038
1038
|
const streamEvents = (flags.literalPrompt || flags.literalWorker)
|
|
1039
|
-
? {
|
|
1040
|
-
onStep: () => {
|
|
1041
|
-
process.stderr.write("JEO_MESSENGER_STEP\n");
|
|
1042
|
-
},
|
|
1043
|
-
onAssistant: (_raw: string, invocation: any) => {
|
|
1044
|
-
if (invocation?.tool) {
|
|
1045
|
-
const summary = summarizeForgeInvocation(invocation.tool, invocation.arguments);
|
|
1046
|
-
process.stderr.write(`JEO_MESSENGER_ACTIVITY ${summary.title}\n`);
|
|
1047
|
-
}
|
|
1048
|
-
},
|
|
1049
|
-
onToolResult: (tool: string) => {
|
|
1050
|
-
process.stderr.write(`JEO_MESSENGER_ACTIVITY Finished ${tool}\n`);
|
|
1051
|
-
},
|
|
1052
|
-
onNotice: (msg: string) => {
|
|
1053
|
-
process.stderr.write(`JEO_MESSENGER_ACTIVITY ${msg}\n`);
|
|
1054
|
-
},
|
|
1055
|
-
onReasoningStart: () => {
|
|
1056
|
-
process.stderr.write("JEO_MESSENGER_ACTIVITY Thinking...\n");
|
|
1057
|
-
},
|
|
1058
|
-
}
|
|
1039
|
+
? createMessengerActivityEvents(text => process.stderr.write(`JEO_MESSENGER_ACTIVITY ${text}\n`))
|
|
1059
1040
|
: createStreamEvents(initialStepLimit);
|
|
1060
1041
|
let queueBusyInput: ((chunk: string) => boolean) | undefined;
|
|
1061
1042
|
let queueBusyPasteActive: (() => boolean) | undefined;
|
|
@@ -1,30 +1,26 @@
|
|
|
1
1
|
import type { AgentLoopEvents, ToolInvocation } from "../agent/engine";
|
|
2
2
|
import type { MessengerActivityReporter } from "./types";
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Derive one-line progress from session events: the model's declared tool intent (falling back to the
|
|
6
|
-
* tool name) and long-running lifecycle notices. Raw tool arguments, results and errors never surface.
|
|
7
|
-
*/
|
|
4
|
+
/** Derive bounded progress without exposing tool arguments, results, or provider errors. */
|
|
8
5
|
export function createMessengerActivityEvents(report: MessengerActivityReporter): AgentLoopEvents {
|
|
9
6
|
let step = 0;
|
|
10
7
|
return {
|
|
8
|
+
onStep(current) {
|
|
9
|
+
step = current;
|
|
10
|
+
report(`Step ${step} · Thinking`);
|
|
11
|
+
},
|
|
11
12
|
onAssistant(_raw: string, invocation: ToolInvocation | null) {
|
|
12
13
|
if (!invocation || invocation.tool === "done") return;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
: `Using ${invocation.tool}`;
|
|
20
|
-
report(`Step ${step} · ${intent}`);
|
|
14
|
+
const tool = /^[a-zA-Z0-9_-]{1,40}$/.test(invocation.tool) ? invocation.tool : "tool";
|
|
15
|
+
report(`Step ${step} · Running ${tool}`);
|
|
16
|
+
},
|
|
17
|
+
onToolResult(tool, success) {
|
|
18
|
+
const name = /^[a-zA-Z0-9_-]{1,40}$/.test(tool) ? tool : "tool";
|
|
19
|
+
report(`Step ${step} · ${name} ${success ? "finished" : "failed"}`);
|
|
21
20
|
},
|
|
22
21
|
onNotice(message: string) {
|
|
23
|
-
if (/compact/i.test(message))
|
|
24
|
-
|
|
25
|
-
} else if (/retry|rate limit/i.test(message)) {
|
|
26
|
-
report("Retrying after a provider error");
|
|
27
|
-
}
|
|
22
|
+
if (/compact/i.test(message)) report("Compacting context");
|
|
23
|
+
else if (/retry|rate limit/i.test(message)) report("Retrying after a provider error");
|
|
28
24
|
},
|
|
29
25
|
};
|
|
30
26
|
}
|
package/src/messenger/discord.ts
CHANGED
|
@@ -344,6 +344,7 @@ export function createDiscordAdapter(
|
|
|
344
344
|
}
|
|
345
345
|
};
|
|
346
346
|
const activityMessages = new Map<string, string>();
|
|
347
|
+
const activityHistory = new Map<string, string[]>();
|
|
347
348
|
const headers = (): Record<string, string> => {
|
|
348
349
|
if (!token) throw new DiscordConfigurationError("Discord bot token is missing");
|
|
349
350
|
return { Authorization: `Bot ${token}`, "Content-Type": "application/json" };
|
|
@@ -531,43 +532,39 @@ export function createDiscordAdapter(
|
|
|
531
532
|
deps.fetch,
|
|
532
533
|
);
|
|
533
534
|
},
|
|
534
|
-
async activity(message, text, signal) {
|
|
535
|
+
async activity(message, text, signal, outcome = "success") {
|
|
535
536
|
const channelId = message.threadId ?? message.channelId;
|
|
536
537
|
const key = JSON.stringify([channelId, message.messageId]);
|
|
537
538
|
const messages = `${DISCORD_API}/channels/${encodeURIComponent(channelId)}/messages`;
|
|
538
539
|
const statusId = activityMessages.get(key);
|
|
540
|
+
const previous = activityHistory.get(key) ?? [];
|
|
539
541
|
if (text === undefined) {
|
|
540
542
|
if (!statusId) return;
|
|
543
|
+
const label = outcome === "success" ? "✅ Complete" : outcome === "failure" ? "❌ Failed" : "⏹ Cancelled";
|
|
541
544
|
try {
|
|
542
545
|
await messengerFetchJson(
|
|
543
546
|
`${messages}/${encodeURIComponent(statusId)}`,
|
|
544
|
-
{
|
|
545
|
-
|
|
546
|
-
headers: headers(),
|
|
547
|
-
body: JSON.stringify({ content: "✅ Complete", allowed_mentions: { parse: [] } }),
|
|
548
|
-
},
|
|
549
|
-
signal,
|
|
550
|
-
deps.fetch,
|
|
547
|
+
{ method: "PATCH", headers: headers(), body: JSON.stringify({ content: [label, ...previous].join("\n"), allowed_mentions: { parse: [] } }) },
|
|
548
|
+
signal, deps.fetch,
|
|
551
549
|
);
|
|
552
550
|
} catch (error) {
|
|
553
551
|
if (!(error instanceof MessengerHttpError && error.status === 404)) throw error;
|
|
554
552
|
}
|
|
555
553
|
activityMessages.delete(key);
|
|
554
|
+
activityHistory.delete(key);
|
|
556
555
|
return;
|
|
557
556
|
}
|
|
558
|
-
|
|
557
|
+
// Keep only a short, bounded history of delivered updates in one editable message.
|
|
558
|
+
const history = [...previous, `• ${text}`].slice(-6);
|
|
559
|
+
const content = ["⏳ In progress", ...history].join("\n");
|
|
559
560
|
if (statusId) {
|
|
560
561
|
try {
|
|
561
562
|
await messengerFetchJson(
|
|
562
563
|
`${messages}/${encodeURIComponent(statusId)}`,
|
|
563
|
-
{
|
|
564
|
-
|
|
565
|
-
headers: headers(),
|
|
566
|
-
body: JSON.stringify({ content, allowed_mentions: { parse: [] } }),
|
|
567
|
-
},
|
|
568
|
-
signal,
|
|
569
|
-
deps.fetch,
|
|
564
|
+
{ method: "PATCH", headers: headers(), body: JSON.stringify({ content, allowed_mentions: { parse: [] } }) },
|
|
565
|
+
signal, deps.fetch,
|
|
570
566
|
);
|
|
567
|
+
activityHistory.set(key, history);
|
|
571
568
|
return;
|
|
572
569
|
} catch (error) {
|
|
573
570
|
if (!(error instanceof MessengerHttpError && error.status === 404)) throw error;
|
|
@@ -576,17 +573,13 @@ export function createDiscordAdapter(
|
|
|
576
573
|
}
|
|
577
574
|
const created = await messengerFetchJson(
|
|
578
575
|
messages,
|
|
579
|
-
{
|
|
580
|
-
|
|
581
|
-
headers: headers(),
|
|
582
|
-
body: JSON.stringify({ content, allowed_mentions: { parse: [] }, flags: DISCORD_ACTIVITY_FLAGS }),
|
|
583
|
-
},
|
|
584
|
-
signal,
|
|
585
|
-
deps.fetch,
|
|
576
|
+
{ method: "POST", headers: headers(), body: JSON.stringify({ content, allowed_mentions: { parse: [] }, flags: DISCORD_ACTIVITY_FLAGS }) },
|
|
577
|
+
signal, deps.fetch,
|
|
586
578
|
);
|
|
587
579
|
if (!isRecord(created) || typeof created.id !== "string" || !created.id)
|
|
588
580
|
throw new Error("Discord activity message returned no ID");
|
|
589
581
|
activityMessages.set(key, created.id);
|
|
582
|
+
activityHistory.set(key, history);
|
|
590
583
|
},
|
|
591
584
|
async send(message, text, signal) {
|
|
592
585
|
let files: { name: string; data: Uint8Array }[] = [];
|
package/src/messenger/gateway.ts
CHANGED
|
@@ -33,8 +33,8 @@ export function activityLine(text: string): string {
|
|
|
33
33
|
|
|
34
34
|
export interface ActivityReporter {
|
|
35
35
|
report: MessengerActivityReporter;
|
|
36
|
-
/** Stop updates and
|
|
37
|
-
close(): Promise<void>;
|
|
36
|
+
/** Stop updates and finalize the status; idempotent and never rejects. */
|
|
37
|
+
close(outcome?: "success" | "failure" | "cancelled"): Promise<void>;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const NO_ACTIVITY: ActivityReporter = { report() {}, close: () => Promise.resolve() };
|
|
@@ -132,7 +132,7 @@ export function createActivityReporter(
|
|
|
132
132
|
pumping = true;
|
|
133
133
|
pump = run();
|
|
134
134
|
},
|
|
135
|
-
close() {
|
|
135
|
+
close(outcome = "success") {
|
|
136
136
|
closing ??= (async () => {
|
|
137
137
|
closed = true;
|
|
138
138
|
wake?.();
|
|
@@ -140,7 +140,7 @@ export function createActivityReporter(
|
|
|
140
140
|
if (!shown) return;
|
|
141
141
|
for (let attempt = 0; ; attempt++) {
|
|
142
142
|
try {
|
|
143
|
-
await boundedActivity(bounded => activity.call(adapter, destination, undefined, bounded));
|
|
143
|
+
await boundedActivity(bounded => activity.call(adapter, destination, undefined, bounded, outcome));
|
|
144
144
|
return;
|
|
145
145
|
} catch (error) {
|
|
146
146
|
const wait =
|
|
@@ -340,6 +340,7 @@ export function createMessengerGateway(
|
|
|
340
340
|
conversationTails.set(conversation, tail);
|
|
341
341
|
await previous;
|
|
342
342
|
activity = createActivityReporter(adapter, destination, signal, activityIntervalMs);
|
|
343
|
+
activity.report("Starting request");
|
|
343
344
|
let text: string;
|
|
344
345
|
try {
|
|
345
346
|
text = await reply(destination, signal, activity.report);
|
|
@@ -353,9 +354,6 @@ export function createMessengerGateway(
|
|
|
353
354
|
}
|
|
354
355
|
if (signal.aborted) return;
|
|
355
356
|
text = "The request could not be completed. Please try again.";
|
|
356
|
-
} finally {
|
|
357
|
-
// Retire the status line alongside reply delivery rather than delaying the reply on it.
|
|
358
|
-
void activity.close();
|
|
359
357
|
}
|
|
360
358
|
if (!signal.aborted && text.trim()) {
|
|
361
359
|
// A failed send may already have delivered a chunk: never retry the entire reply.
|
|
@@ -363,9 +361,10 @@ export function createMessengerGateway(
|
|
|
363
361
|
}
|
|
364
362
|
if (!signal.aborted) status(failed ? "failure" : "success");
|
|
365
363
|
} catch {
|
|
364
|
+
failed = true;
|
|
366
365
|
if (!signal.aborted) status("failure");
|
|
367
366
|
} finally {
|
|
368
|
-
await activity.close();
|
|
367
|
+
await activity.close(failed ? "failure" : signal.aborted ? "cancelled" : "success");
|
|
369
368
|
release();
|
|
370
369
|
if (tail && conversationTails.get(conversation) === tail) conversationTails.delete(conversation);
|
|
371
370
|
resolve();
|
package/src/messenger/types.ts
CHANGED
|
@@ -31,11 +31,8 @@ export interface MessengerAdapter {
|
|
|
31
31
|
status: "processing" | "success" | "failure",
|
|
32
32
|
signal?: AbortSignal,
|
|
33
33
|
): Promise<void>;
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
* later calls; `undefined` removes it. The gateway serializes and throttles calls per request.
|
|
37
|
-
*/
|
|
38
|
-
activity?(message: MessengerMessage, text: string | undefined, signal?: AbortSignal): Promise<void>;
|
|
34
|
+
/** Update the request's progress; undefined finishes it with the supplied outcome. */
|
|
35
|
+
activity?(message: MessengerMessage, text: string | undefined, signal?: AbortSignal, outcome?: "success" | "failure" | "cancelled"): Promise<void>;
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
export interface MessengerPlatformConfig {
|