@kenkaiiii/gg-boss 4.3.164 → 4.4.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/dist/{chunk-SSDL6C2P.js → chunk-5ENJR6XI.js} +23729 -24018
- package/dist/{chunk-SSDL6C2P.js.map → chunk-5ENJR6XI.js.map} +1 -1
- package/dist/cli.js +316 -714
- package/dist/cli.js.map +1 -1
- package/dist/{devtools-OQIIURAD.js → devtools-XF5S3NSL.js} +5 -5
- package/dist/{devtools-OQIIURAD.js.map → devtools-XF5S3NSL.js.map} +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -4
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createRequire as __createRequire } from "node:module"; const require =
|
|
|
3
3
|
import {
|
|
4
4
|
AnimationProvider,
|
|
5
5
|
AssistantMessage,
|
|
6
|
+
AuthStorage,
|
|
6
7
|
Box_default,
|
|
7
8
|
ChatControls,
|
|
8
9
|
ChatInputStack,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
MODELS,
|
|
16
17
|
MessageResponse,
|
|
17
18
|
RESPONSE_LEFT_PADDING,
|
|
19
|
+
TelegramBot,
|
|
18
20
|
TerminalSizeProvider,
|
|
19
21
|
Text,
|
|
20
22
|
ThemeContext,
|
|
@@ -28,17 +30,21 @@ import {
|
|
|
28
30
|
buildToolGroupSummary,
|
|
29
31
|
closeLogger,
|
|
30
32
|
color,
|
|
33
|
+
createAutoUpdater,
|
|
31
34
|
dim,
|
|
32
35
|
formatHistoryWrite,
|
|
33
36
|
getAppPaths,
|
|
34
37
|
getBossState,
|
|
35
38
|
getContextWindow,
|
|
39
|
+
getDefaultModel,
|
|
40
|
+
getModel,
|
|
36
41
|
getNextThinkingLevel,
|
|
37
42
|
getSplashAudioDurationMs,
|
|
38
43
|
getTranscriptItemMarginTop,
|
|
39
44
|
gradientLine,
|
|
40
45
|
indent,
|
|
41
46
|
initLogger,
|
|
47
|
+
isModelLoaded,
|
|
42
48
|
loadSettings,
|
|
43
49
|
loadTheme,
|
|
44
50
|
log,
|
|
@@ -48,6 +54,7 @@ import {
|
|
|
48
54
|
require_react,
|
|
49
55
|
saveSettings,
|
|
50
56
|
serializeCompletedItemToTerminalHistory,
|
|
57
|
+
setProgressCallback,
|
|
51
58
|
setStreamDiagnostic,
|
|
52
59
|
shouldSeparateTranscriptItemKinds,
|
|
53
60
|
shouldTopSpaceStreamingAssistant,
|
|
@@ -56,6 +63,7 @@ import {
|
|
|
56
63
|
subscribeToBossStore,
|
|
57
64
|
tasksStore,
|
|
58
65
|
toolTonePalette,
|
|
66
|
+
transcribeVoice,
|
|
59
67
|
truncatePlain,
|
|
60
68
|
useAnimationActive,
|
|
61
69
|
useAnimationTick,
|
|
@@ -68,7 +76,7 @@ import {
|
|
|
68
76
|
use_input_default,
|
|
69
77
|
use_stdout_default,
|
|
70
78
|
wrapPlain
|
|
71
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-5ENJR6XI.js";
|
|
72
80
|
import "./chunk-JEGMYLRS.js";
|
|
73
81
|
import {
|
|
74
82
|
source_default
|
|
@@ -361,7 +369,7 @@ init_esm_shims();
|
|
|
361
369
|
// package.json
|
|
362
370
|
var package_default = {
|
|
363
371
|
name: "@kenkaiiii/gg-boss",
|
|
364
|
-
version: "4.
|
|
372
|
+
version: "4.4.0",
|
|
365
373
|
type: "module",
|
|
366
374
|
description: "Orchestrator agent that drives multiple ggcoder sessions across projects from a single chat",
|
|
367
375
|
license: "MIT",
|
|
@@ -387,6 +395,7 @@ var package_default = {
|
|
|
387
395
|
devDependencies: {
|
|
388
396
|
"@kenkaiiii/gg-agent": "workspace:*",
|
|
389
397
|
"@kenkaiiii/gg-ai": "workspace:*",
|
|
398
|
+
"@kenkaiiii/gg-core": "workspace:*",
|
|
390
399
|
"@kenkaiiii/ggcoder": "workspace:*",
|
|
391
400
|
"@types/node": "^25.6.0",
|
|
392
401
|
"@types/react": "^19.2.14",
|
|
@@ -669,317 +678,6 @@ async function runLinkCommand() {
|
|
|
669
678
|
init_esm_shims();
|
|
670
679
|
import path3 from "path";
|
|
671
680
|
import fs3 from "fs/promises";
|
|
672
|
-
|
|
673
|
-
// src/voice-transcriber.ts
|
|
674
|
-
init_esm_shims();
|
|
675
|
-
var TARGET_SAMPLE_RATE = 16e3;
|
|
676
|
-
var MODEL_ID = "Xenova/whisper-tiny.en";
|
|
677
|
-
var transcriber = null;
|
|
678
|
-
var loadPromise = null;
|
|
679
|
-
var onProgress = null;
|
|
680
|
-
function setProgressCallback(cb) {
|
|
681
|
-
onProgress = cb;
|
|
682
|
-
}
|
|
683
|
-
function resample(audio, fromRate, toRate) {
|
|
684
|
-
if (fromRate === toRate) return audio;
|
|
685
|
-
const ratio = fromRate / toRate;
|
|
686
|
-
const newLength = Math.round(audio.length / ratio);
|
|
687
|
-
const result = new Float32Array(newLength);
|
|
688
|
-
for (let i = 0; i < newLength; i++) {
|
|
689
|
-
const srcIndex = i * ratio;
|
|
690
|
-
const low = Math.floor(srcIndex);
|
|
691
|
-
const high = Math.min(low + 1, audio.length - 1);
|
|
692
|
-
const frac = srcIndex - low;
|
|
693
|
-
result[i] = audio[low] * (1 - frac) + audio[high] * frac;
|
|
694
|
-
}
|
|
695
|
-
return result;
|
|
696
|
-
}
|
|
697
|
-
function downmixToMono(channelData) {
|
|
698
|
-
if (channelData.length === 0) return new Float32Array();
|
|
699
|
-
if (channelData.length === 1) return channelData[0];
|
|
700
|
-
const samples = channelData[0].length;
|
|
701
|
-
const out = new Float32Array(samples);
|
|
702
|
-
const scale = 1 / channelData.length;
|
|
703
|
-
for (let i = 0; i < samples; i++) {
|
|
704
|
-
let mixed = 0;
|
|
705
|
-
for (const channel of channelData) mixed += channel[i] ?? 0;
|
|
706
|
-
out[i] = mixed * scale;
|
|
707
|
-
}
|
|
708
|
-
return out;
|
|
709
|
-
}
|
|
710
|
-
async function decodeOggOpus(buffer) {
|
|
711
|
-
const { OggOpusDecoder } = await import("ogg-opus-decoder");
|
|
712
|
-
const decoder = new OggOpusDecoder();
|
|
713
|
-
await decoder.ready;
|
|
714
|
-
try {
|
|
715
|
-
const decoded = await decoder.decodeFile(buffer);
|
|
716
|
-
if (!decoded.channelData?.length || !decoded.channelData[0]?.length) {
|
|
717
|
-
throw new Error("Decoded audio is empty");
|
|
718
|
-
}
|
|
719
|
-
const mono = downmixToMono(decoded.channelData);
|
|
720
|
-
return resample(mono, decoded.sampleRate, TARGET_SAMPLE_RATE);
|
|
721
|
-
} finally {
|
|
722
|
-
decoder.free();
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
async function getTranscriber() {
|
|
726
|
-
if (transcriber) return transcriber;
|
|
727
|
-
if (!loadPromise) {
|
|
728
|
-
loadPromise = (async () => {
|
|
729
|
-
const { pipeline } = await import("@huggingface/transformers");
|
|
730
|
-
const instance = await pipeline("automatic-speech-recognition", MODEL_ID, {
|
|
731
|
-
dtype: "fp32",
|
|
732
|
-
progress_callback: onProgress ?? void 0
|
|
733
|
-
});
|
|
734
|
-
transcriber = instance;
|
|
735
|
-
return instance;
|
|
736
|
-
})();
|
|
737
|
-
}
|
|
738
|
-
return loadPromise;
|
|
739
|
-
}
|
|
740
|
-
function isModelLoaded() {
|
|
741
|
-
return transcriber !== null;
|
|
742
|
-
}
|
|
743
|
-
async function transcribeVoice(fileUrl) {
|
|
744
|
-
const response = await fetch(fileUrl);
|
|
745
|
-
if (!response.ok) throw new Error(`Failed to download voice file: ${response.status}`);
|
|
746
|
-
const buffer = new Uint8Array(await response.arrayBuffer());
|
|
747
|
-
const pcm = await decodeOggOpus(buffer);
|
|
748
|
-
const asr = await getTranscriber();
|
|
749
|
-
const result = await asr(pcm);
|
|
750
|
-
const text = Array.isArray(result) ? result[0]?.text : result.text;
|
|
751
|
-
return (text ?? "").trim();
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
// src/telegram.ts
|
|
755
|
-
init_esm_shims();
|
|
756
|
-
var TELEGRAM_API = "https://api.telegram.org";
|
|
757
|
-
var MAX_MESSAGE_LENGTH = 4096;
|
|
758
|
-
var TelegramBot = class {
|
|
759
|
-
token;
|
|
760
|
-
allowedUserId;
|
|
761
|
-
offset = 0;
|
|
762
|
-
running = false;
|
|
763
|
-
onMessage = null;
|
|
764
|
-
onVoiceMessage = null;
|
|
765
|
-
onCallback = null;
|
|
766
|
-
onBotAdded = null;
|
|
767
|
-
onBotRemoved = null;
|
|
768
|
-
constructor(config) {
|
|
769
|
-
this.token = config.botToken;
|
|
770
|
-
this.allowedUserId = config.allowedUserId;
|
|
771
|
-
}
|
|
772
|
-
/** Register handler for incoming text messages. */
|
|
773
|
-
onText(handler) {
|
|
774
|
-
this.onMessage = handler;
|
|
775
|
-
}
|
|
776
|
-
/** Register handler for incoming voice notes. */
|
|
777
|
-
onVoice(handler) {
|
|
778
|
-
this.onVoiceMessage = handler;
|
|
779
|
-
}
|
|
780
|
-
/** Register handler for inline keyboard button presses. */
|
|
781
|
-
onCallbackQuery(handler) {
|
|
782
|
-
this.onCallback = handler;
|
|
783
|
-
}
|
|
784
|
-
/** Register handler for when the bot is added to a group. */
|
|
785
|
-
onAddedToGroup(handler) {
|
|
786
|
-
this.onBotAdded = handler;
|
|
787
|
-
}
|
|
788
|
-
/** Register handler for when the bot is removed from a group. */
|
|
789
|
-
onRemovedFromGroup(handler) {
|
|
790
|
-
this.onBotRemoved = handler;
|
|
791
|
-
}
|
|
792
|
-
/** Start long polling. Blocks until stop() is called. */
|
|
793
|
-
async start() {
|
|
794
|
-
this.running = true;
|
|
795
|
-
const me = await this.apiCall("getMe");
|
|
796
|
-
if (!me.ok) {
|
|
797
|
-
throw new Error(`Invalid bot token: ${JSON.stringify(me)}`);
|
|
798
|
-
}
|
|
799
|
-
while (this.running) {
|
|
800
|
-
try {
|
|
801
|
-
const updates = await this.getUpdates();
|
|
802
|
-
for (const update of updates) {
|
|
803
|
-
await this.handleUpdate(update);
|
|
804
|
-
}
|
|
805
|
-
} catch (err) {
|
|
806
|
-
if (!this.running) break;
|
|
807
|
-
console.error(`[telegram] Poll error: ${err instanceof Error ? err.message : err}`);
|
|
808
|
-
await sleep(3e3);
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
/** Stop long polling. */
|
|
813
|
-
stop() {
|
|
814
|
-
this.running = false;
|
|
815
|
-
}
|
|
816
|
-
/** Send a text message to a specific chat. Converts markdown and splits long messages. */
|
|
817
|
-
async send(chatId, text, buttons) {
|
|
818
|
-
const converted = toTelegramMarkdown(text);
|
|
819
|
-
const chunks = splitMessage(converted);
|
|
820
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
821
|
-
const isLast = i === chunks.length - 1;
|
|
822
|
-
const replyMarkup = isLast && buttons ? {
|
|
823
|
-
inline_keyboard: buttons.map(
|
|
824
|
-
(row) => row.map((b) => ({ text: b.text, callback_data: b.callback_data }))
|
|
825
|
-
)
|
|
826
|
-
} : void 0;
|
|
827
|
-
await this.apiCall("sendMessage", {
|
|
828
|
-
chat_id: chatId,
|
|
829
|
-
text: chunks[i],
|
|
830
|
-
parse_mode: "Markdown",
|
|
831
|
-
...replyMarkup ? { reply_markup: replyMarkup } : {}
|
|
832
|
-
});
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
/** Send a plain text message (no markdown parsing) to a specific chat. */
|
|
836
|
-
async sendPlain(chatId, text) {
|
|
837
|
-
const chunks = splitMessage(text);
|
|
838
|
-
for (const chunk of chunks) {
|
|
839
|
-
await this.apiCall("sendMessage", {
|
|
840
|
-
chat_id: chatId,
|
|
841
|
-
text: chunk
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
/** Send a typing indicator to a specific chat. */
|
|
846
|
-
async sendTyping(chatId) {
|
|
847
|
-
await this.apiCall("sendChatAction", {
|
|
848
|
-
chat_id: chatId,
|
|
849
|
-
action: "typing"
|
|
850
|
-
});
|
|
851
|
-
}
|
|
852
|
-
/** Get a direct download URL for a Telegram file. */
|
|
853
|
-
async getFileUrl(fileId) {
|
|
854
|
-
const result = await this.apiCall("getFile", { file_id: fileId });
|
|
855
|
-
if (!result.ok) throw new Error(`Failed to get file: ${JSON.stringify(result)}`);
|
|
856
|
-
const filePath = result.result.file_path;
|
|
857
|
-
return `${TELEGRAM_API}/file/bot${this.token}/${filePath}`;
|
|
858
|
-
}
|
|
859
|
-
// ── Private ───────────────────────────────────────────
|
|
860
|
-
async getUpdates() {
|
|
861
|
-
const result = await this.apiCall("getUpdates", {
|
|
862
|
-
offset: this.offset,
|
|
863
|
-
timeout: 30,
|
|
864
|
-
allowed_updates: ["message", "callback_query", "my_chat_member"]
|
|
865
|
-
});
|
|
866
|
-
if (!result.ok || !Array.isArray(result.result)) return [];
|
|
867
|
-
const updates = result.result;
|
|
868
|
-
if (updates.length > 0) {
|
|
869
|
-
this.offset = updates[updates.length - 1].update_id + 1;
|
|
870
|
-
}
|
|
871
|
-
return updates;
|
|
872
|
-
}
|
|
873
|
-
async handleUpdate(update) {
|
|
874
|
-
if (update.message) {
|
|
875
|
-
const msg = update.message;
|
|
876
|
-
if (msg.from.id !== this.allowedUserId) {
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
if (msg.text && this.onMessage) {
|
|
880
|
-
this.onMessage({
|
|
881
|
-
text: msg.text,
|
|
882
|
-
chatId: msg.chat.id,
|
|
883
|
-
chatType: msg.chat.type,
|
|
884
|
-
chatTitle: msg.chat.title
|
|
885
|
-
});
|
|
886
|
-
} else if (msg.voice && this.onVoiceMessage) {
|
|
887
|
-
this.onVoiceMessage({
|
|
888
|
-
fileId: msg.voice.file_id,
|
|
889
|
-
duration: msg.voice.duration,
|
|
890
|
-
chatId: msg.chat.id,
|
|
891
|
-
chatType: msg.chat.type,
|
|
892
|
-
chatTitle: msg.chat.title
|
|
893
|
-
});
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
if (update.my_chat_member) {
|
|
897
|
-
const member = update.my_chat_member;
|
|
898
|
-
const status = member.new_chat_member.status;
|
|
899
|
-
if ((status === "member" || status === "administrator") && this.onBotAdded) {
|
|
900
|
-
this.onBotAdded(member.chat.id, member.chat.title);
|
|
901
|
-
} else if ((status === "left" || status === "kicked") && this.onBotRemoved) {
|
|
902
|
-
this.onBotRemoved(member.chat.id);
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
if (update.callback_query) {
|
|
906
|
-
const cb = update.callback_query;
|
|
907
|
-
if (cb.from.id !== this.allowedUserId) return;
|
|
908
|
-
await this.apiCall("answerCallbackQuery", { callback_query_id: cb.id });
|
|
909
|
-
if (cb.data && this.onCallback) {
|
|
910
|
-
this.onCallback(cb.data, cb.message.chat.id);
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
async apiCall(method, body) {
|
|
915
|
-
const url = `${TELEGRAM_API}/bot${this.token}/${method}`;
|
|
916
|
-
const response = await fetch(url, {
|
|
917
|
-
method: "POST",
|
|
918
|
-
headers: { "Content-Type": "application/json" },
|
|
919
|
-
body: body ? JSON.stringify(body) : void 0
|
|
920
|
-
});
|
|
921
|
-
if (!response.ok) {
|
|
922
|
-
return { ok: false };
|
|
923
|
-
}
|
|
924
|
-
return response.json();
|
|
925
|
-
}
|
|
926
|
-
};
|
|
927
|
-
function toTelegramMarkdown(text) {
|
|
928
|
-
const lines = text.split("\n");
|
|
929
|
-
const result = [];
|
|
930
|
-
let inCodeBlock = false;
|
|
931
|
-
for (const line of lines) {
|
|
932
|
-
if (line.trimStart().startsWith("```")) {
|
|
933
|
-
inCodeBlock = !inCodeBlock;
|
|
934
|
-
result.push(line);
|
|
935
|
-
continue;
|
|
936
|
-
}
|
|
937
|
-
if (inCodeBlock) {
|
|
938
|
-
result.push(line);
|
|
939
|
-
continue;
|
|
940
|
-
}
|
|
941
|
-
let transformed = line;
|
|
942
|
-
const headingMatch = transformed.match(/^(#{1,6})\s+(.+)$/);
|
|
943
|
-
if (headingMatch) {
|
|
944
|
-
transformed = `*${headingMatch[2]}*`;
|
|
945
|
-
result.push(transformed);
|
|
946
|
-
continue;
|
|
947
|
-
}
|
|
948
|
-
if (/^(-{3,}|_{3,}|\*{3,})$/.test(transformed.trim())) {
|
|
949
|
-
result.push("");
|
|
950
|
-
continue;
|
|
951
|
-
}
|
|
952
|
-
transformed = transformed.replace(/\*\*(.+?)\*\*/g, "*$1*");
|
|
953
|
-
result.push(transformed);
|
|
954
|
-
}
|
|
955
|
-
return result.join("\n");
|
|
956
|
-
}
|
|
957
|
-
function splitMessage(text) {
|
|
958
|
-
if (text.length <= MAX_MESSAGE_LENGTH) return [text];
|
|
959
|
-
const chunks = [];
|
|
960
|
-
let remaining = text;
|
|
961
|
-
while (remaining.length > 0) {
|
|
962
|
-
if (remaining.length <= MAX_MESSAGE_LENGTH) {
|
|
963
|
-
chunks.push(remaining);
|
|
964
|
-
break;
|
|
965
|
-
}
|
|
966
|
-
let splitAt = remaining.lastIndexOf("\n", MAX_MESSAGE_LENGTH);
|
|
967
|
-
if (splitAt === -1 || splitAt < MAX_MESSAGE_LENGTH * 0.5) {
|
|
968
|
-
splitAt = remaining.lastIndexOf(" ", MAX_MESSAGE_LENGTH);
|
|
969
|
-
}
|
|
970
|
-
if (splitAt === -1 || splitAt < MAX_MESSAGE_LENGTH * 0.5) {
|
|
971
|
-
splitAt = MAX_MESSAGE_LENGTH;
|
|
972
|
-
}
|
|
973
|
-
chunks.push(remaining.slice(0, splitAt));
|
|
974
|
-
remaining = remaining.slice(splitAt).trimStart();
|
|
975
|
-
}
|
|
976
|
-
return chunks;
|
|
977
|
-
}
|
|
978
|
-
function sleep(ms) {
|
|
979
|
-
return new Promise((r) => setTimeout(r, ms));
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
// src/serve-mode.ts
|
|
983
681
|
function getTelegramConfigPath() {
|
|
984
682
|
return path3.join(getAppPaths().agentDir, "boss", "telegram.json");
|
|
985
683
|
}
|
|
@@ -1538,7 +1236,7 @@ function printSetupBanner() {
|
|
|
1538
1236
|
|
|
1539
1237
|
// src/orchestrator-app.tsx
|
|
1540
1238
|
init_esm_shims();
|
|
1541
|
-
var
|
|
1239
|
+
var import_react14 = __toESM(require_react(), 1);
|
|
1542
1240
|
|
|
1543
1241
|
// ../ggcoder/dist/ui/components/index.js
|
|
1544
1242
|
init_esm_shims();
|
|
@@ -1548,20 +1246,15 @@ init_esm_shims();
|
|
|
1548
1246
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
1549
1247
|
var import_react3 = __toESM(require_react(), 1);
|
|
1550
1248
|
|
|
1551
|
-
// ../ggcoder/dist/ui/components/
|
|
1249
|
+
// ../ggcoder/dist/ui/components/SelectList.js
|
|
1552
1250
|
init_esm_shims();
|
|
1553
1251
|
var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
|
|
1554
1252
|
var import_react4 = __toESM(require_react(), 1);
|
|
1555
|
-
|
|
1556
|
-
// ../ggcoder/dist/ui/components/SelectList.js
|
|
1557
|
-
init_esm_shims();
|
|
1558
|
-
var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
|
|
1559
|
-
var import_react5 = __toESM(require_react(), 1);
|
|
1560
1253
|
function SelectList({ items, onSelect, onCancel, initialIndex = 0, windowSize }) {
|
|
1561
1254
|
const theme = useTheme();
|
|
1562
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
1563
|
-
const [filter, setFilter] = (0,
|
|
1564
|
-
const filtered = (0,
|
|
1255
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react4.useState)(initialIndex);
|
|
1256
|
+
const [filter, setFilter] = (0, import_react4.useState)("");
|
|
1257
|
+
const filtered = (0, import_react4.useMemo)(() => {
|
|
1565
1258
|
if (!filter)
|
|
1566
1259
|
return items;
|
|
1567
1260
|
const lower = filter.toLowerCase();
|
|
@@ -1608,30 +1301,30 @@ function SelectList({ items, onSelect, onCancel, initialIndex = 0, windowSize })
|
|
|
1608
1301
|
const visible = useWindow ? filtered.slice(start, end) : filtered;
|
|
1609
1302
|
const hasAbove = useWindow && start > 0;
|
|
1610
1303
|
const hasBelow = useWindow && end < total;
|
|
1611
|
-
return (0,
|
|
1304
|
+
return (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", children: [filter && (0, import_jsx_runtime4.jsx)(Box_default, { marginBottom: 1, children: (0, import_jsx_runtime4.jsxs)(Text, { color: theme.textDim, children: ["Filter: ", filter] }) }), hasAbove && (0, import_jsx_runtime4.jsxs)(Text, { color: theme.textDim, children: [" \u2191 ", start, " more"] }), visible.map((item, i) => {
|
|
1612
1305
|
const index = useWindow ? start + i : i;
|
|
1613
|
-
return (0,
|
|
1614
|
-
}), hasBelow && (0,
|
|
1306
|
+
return (0, import_jsx_runtime4.jsxs)(Box_default, { children: [(0, import_jsx_runtime4.jsxs)(Text, { color: index === clampedIndex ? theme.primary : theme.text, children: [index === clampedIndex ? "\u276F " : " ", item.label] }), item.description && (0, import_jsx_runtime4.jsxs)(Text, { color: theme.textDim, children: [" \u2014 ", item.description] })] }, item.value);
|
|
1307
|
+
}), hasBelow && (0, import_jsx_runtime4.jsxs)(Text, { color: theme.textDim, children: [" \u2193 ", total - end, " more"] }), filtered.length === 0 && (0, import_jsx_runtime4.jsx)(Text, { color: theme.textDim, children: "No matches" }), (0, import_jsx_runtime4.jsx)(Box_default, { marginTop: 1, children: (0, import_jsx_runtime4.jsx)(Text, { color: theme.textDim, children: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc cancel" }) })] });
|
|
1615
1308
|
}
|
|
1616
1309
|
|
|
1617
1310
|
// ../ggcoder/dist/ui/components/SessionSelector.js
|
|
1618
1311
|
init_esm_shims();
|
|
1619
|
-
var
|
|
1620
|
-
var
|
|
1312
|
+
var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
|
|
1313
|
+
var import_react5 = __toESM(require_react(), 1);
|
|
1621
1314
|
|
|
1622
1315
|
// ../ggcoder/dist/ui/components/SettingsSelector.js
|
|
1623
1316
|
init_esm_shims();
|
|
1624
|
-
var
|
|
1625
|
-
var
|
|
1317
|
+
var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
|
|
1318
|
+
var import_react6 = __toESM(require_react(), 1);
|
|
1626
1319
|
|
|
1627
1320
|
// src/boss-chat-screen.tsx
|
|
1628
1321
|
init_esm_shims();
|
|
1629
|
-
var
|
|
1322
|
+
var import_react12 = __toESM(require_react(), 1);
|
|
1630
1323
|
|
|
1631
1324
|
// src/boss-footer.tsx
|
|
1632
1325
|
init_esm_shims();
|
|
1633
|
-
var
|
|
1634
|
-
var
|
|
1326
|
+
var import_react7 = __toESM(require_react(), 1);
|
|
1327
|
+
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
1635
1328
|
var PARTIAL_BLOCKS = [" ", "\u258F", "\u258E", "\u258D", "\u258C", "\u258B", "\u258A", "\u2589", "\u2588"];
|
|
1636
1329
|
var LIGHT_SHADE = "\u2591";
|
|
1637
1330
|
var BAR_WIDTH = 8;
|
|
@@ -1685,7 +1378,7 @@ function renderContextBar({
|
|
|
1685
1378
|
const cellFill = Math.max(0, Math.min(1, fillFloat - i));
|
|
1686
1379
|
const eighths = Math.round(cellFill * 8);
|
|
1687
1380
|
barChars.push(
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
1381
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: eighths > 0 ? contextColor : dimColor, children: eighths > 0 ? PARTIAL_BLOCKS[eighths] : LIGHT_SHADE }, i)
|
|
1689
1382
|
);
|
|
1690
1383
|
}
|
|
1691
1384
|
return barChars;
|
|
@@ -1706,11 +1399,11 @@ function BossFooter({
|
|
|
1706
1399
|
const theme = useTheme();
|
|
1707
1400
|
const { columns } = useTerminalSize();
|
|
1708
1401
|
if (exitPending) {
|
|
1709
|
-
return /* @__PURE__ */ (0,
|
|
1402
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { paddingLeft: 1, paddingRight: 1, width: columns, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: theme.warning, children: "Press Ctrl+C again to exit" }) });
|
|
1710
1403
|
}
|
|
1711
1404
|
const contextPct = getBossFooterContextPercent(bossModel, tokensIn);
|
|
1712
1405
|
const contextColor = getContextColor(contextPct, theme);
|
|
1713
|
-
const sep = /* @__PURE__ */ (0,
|
|
1406
|
+
const sep = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: theme.border, children: " \u2502 " });
|
|
1714
1407
|
const bossName = shortModel(bossModel);
|
|
1715
1408
|
const workerName = shortModel(workerModel);
|
|
1716
1409
|
const thinkingText = getBossFooterThinkingLabel(bossThinkingLevel);
|
|
@@ -1727,48 +1420,48 @@ function BossFooter({
|
|
|
1727
1420
|
const fitsOnOneLine = leftText.length + rightLen <= availableWidth;
|
|
1728
1421
|
const hideRadio = !!radioName && leftText.length + rightLen > availableWidth + 8;
|
|
1729
1422
|
const compactUpdate = !!updateText && leftText.length + rightLen > availableWidth + 12;
|
|
1730
|
-
const rightContent = /* @__PURE__ */ (0,
|
|
1731
|
-
/* @__PURE__ */ (0,
|
|
1732
|
-
/* @__PURE__ */ (0,
|
|
1423
|
+
const rightContent = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1424
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: barChars }),
|
|
1425
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: contextColor, children: [
|
|
1733
1426
|
" ",
|
|
1734
1427
|
contextPct,
|
|
1735
1428
|
"%"
|
|
1736
1429
|
] }),
|
|
1737
1430
|
sep,
|
|
1738
|
-
/* @__PURE__ */ (0,
|
|
1431
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: theme.primary, bold: true, children: bossName }),
|
|
1739
1432
|
sep,
|
|
1740
|
-
/* @__PURE__ */ (0,
|
|
1741
|
-
/* @__PURE__ */ (0,
|
|
1433
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: theme.textDim, children: "workers " }),
|
|
1434
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: COLORS.accent, bold: true, children: workerName }),
|
|
1742
1435
|
sep,
|
|
1743
|
-
/* @__PURE__ */ (0,
|
|
1744
|
-
radioName && !hideRadio && /* @__PURE__ */ (0,
|
|
1436
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: getThinkingColor(bossThinkingLevel, theme), bold: bossThinkingLevel === "high", children: thinkingText }),
|
|
1437
|
+
radioName && !hideRadio && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1745
1438
|
sep,
|
|
1746
|
-
/* @__PURE__ */ (0,
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: theme.secondary, children: [
|
|
1747
1440
|
"\u266A ",
|
|
1748
1441
|
radioName
|
|
1749
1442
|
] })
|
|
1750
1443
|
] }),
|
|
1751
|
-
updateText && /* @__PURE__ */ (0,
|
|
1444
|
+
updateText && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1752
1445
|
sep,
|
|
1753
|
-
/* @__PURE__ */ (0,
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: theme.success, bold: true, wrap: "truncate", children: compactUpdate ? "Update ready" : updateText })
|
|
1754
1447
|
] })
|
|
1755
1448
|
] });
|
|
1756
1449
|
if (fitsOnOneLine) {
|
|
1757
|
-
return /* @__PURE__ */ (0,
|
|
1758
|
-
/* @__PURE__ */ (0,
|
|
1759
|
-
/* @__PURE__ */ (0,
|
|
1450
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { paddingLeft: 1, paddingRight: 1, width: columns, children: [
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: theme.textDim, wrap: "truncate", children: leftText }) }),
|
|
1452
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { flexShrink: 0, children: rightContent })
|
|
1760
1453
|
] });
|
|
1761
1454
|
}
|
|
1762
|
-
return /* @__PURE__ */ (0,
|
|
1763
|
-
/* @__PURE__ */ (0,
|
|
1764
|
-
/* @__PURE__ */ (0,
|
|
1455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 1, paddingRight: 1, width: columns, children: [
|
|
1456
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: theme.textDim, wrap: "truncate", children: leftText }) }),
|
|
1457
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { children: rightContent })
|
|
1765
1458
|
] });
|
|
1766
1459
|
}
|
|
1767
1460
|
|
|
1768
1461
|
// src/boss-model-selector.tsx
|
|
1769
1462
|
init_esm_shims();
|
|
1770
|
-
var
|
|
1771
|
-
var
|
|
1463
|
+
var import_react8 = __toESM(require_react(), 1);
|
|
1464
|
+
var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
|
|
1772
1465
|
var MAX_MODELS_TO_SHOW = 8;
|
|
1773
1466
|
var PROVIDER_LABEL = {
|
|
1774
1467
|
anthropic: "Anthropic",
|
|
@@ -1806,9 +1499,9 @@ function BossModelSelectList({
|
|
|
1806
1499
|
}) {
|
|
1807
1500
|
const theme = useTheme();
|
|
1808
1501
|
const { columns } = useTerminalSize();
|
|
1809
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
1810
|
-
const [filter, setFilter] = (0,
|
|
1811
|
-
const filtered = (0,
|
|
1502
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react8.useState)(initialIndex);
|
|
1503
|
+
const [filter, setFilter] = (0, import_react8.useState)("");
|
|
1504
|
+
const filtered = (0, import_react8.useMemo)(() => {
|
|
1812
1505
|
if (!filter) return items;
|
|
1813
1506
|
const lower = filter.toLowerCase();
|
|
1814
1507
|
return items.filter(
|
|
@@ -1854,38 +1547,38 @@ function BossModelSelectList({
|
|
|
1854
1547
|
const width = Math.max(20, columns);
|
|
1855
1548
|
const maxLabelLength = Math.max(0, ...filtered.map((item) => item.label.length));
|
|
1856
1549
|
const labelColumnWidth = Math.min(maxLabelLength, Math.floor(width * 0.5));
|
|
1857
|
-
return /* @__PURE__ */ (0,
|
|
1858
|
-
filter && /* @__PURE__ */ (0,
|
|
1550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, width, children: [
|
|
1551
|
+
filter && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: theme.textDim, children: [
|
|
1859
1552
|
"Filter: ",
|
|
1860
1553
|
filter
|
|
1861
1554
|
] }),
|
|
1862
|
-
start > 0 && /* @__PURE__ */ (0,
|
|
1555
|
+
start > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: theme.text, children: "\u25B2" }),
|
|
1863
1556
|
visible.map((item, i) => {
|
|
1864
1557
|
const actualIndex = start + i;
|
|
1865
1558
|
const isSelected = actualIndex === idx;
|
|
1866
1559
|
const textColor = isSelected ? theme.commandColor : theme.textDim;
|
|
1867
|
-
return /* @__PURE__ */ (0,
|
|
1560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1868
1561
|
Box_default,
|
|
1869
1562
|
{
|
|
1870
1563
|
flexDirection: "row",
|
|
1871
1564
|
backgroundColor: isSelected ? theme.border : void 0,
|
|
1872
1565
|
children: [
|
|
1873
|
-
/* @__PURE__ */ (0,
|
|
1874
|
-
/* @__PURE__ */ (0,
|
|
1566
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box_default, { width: labelColumnWidth, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: textColor, children: item.label }) }),
|
|
1567
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box_default, { flexGrow: 1, paddingLeft: 3, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: textColor, wrap: "truncate", children: item.description.slice(0, 100) }) })
|
|
1875
1568
|
]
|
|
1876
1569
|
},
|
|
1877
1570
|
item.value
|
|
1878
1571
|
);
|
|
1879
1572
|
}),
|
|
1880
|
-
end < total && /* @__PURE__ */ (0,
|
|
1881
|
-
total > MAX_MODELS_TO_SHOW && /* @__PURE__ */ (0,
|
|
1573
|
+
end < total && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: theme.textDim, children: "\u25BC" }),
|
|
1574
|
+
total > MAX_MODELS_TO_SHOW && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: theme.textDim, children: [
|
|
1882
1575
|
"(",
|
|
1883
1576
|
idx + 1,
|
|
1884
1577
|
"/",
|
|
1885
1578
|
total,
|
|
1886
1579
|
")"
|
|
1887
1580
|
] }),
|
|
1888
|
-
total === 0 && /* @__PURE__ */ (0,
|
|
1581
|
+
total === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { color: theme.textDim, children: "No matches" })
|
|
1889
1582
|
] });
|
|
1890
1583
|
}
|
|
1891
1584
|
function BossModelSelector({
|
|
@@ -1895,7 +1588,7 @@ function BossModelSelector({
|
|
|
1895
1588
|
currentProvider
|
|
1896
1589
|
}) {
|
|
1897
1590
|
const currentValue = `${currentProvider}:${currentModel}`;
|
|
1898
|
-
const items = (0,
|
|
1591
|
+
const items = (0, import_react8.useMemo)(
|
|
1899
1592
|
() => MODELS.map((model) => {
|
|
1900
1593
|
const value = `${model.provider}:${model.id}`;
|
|
1901
1594
|
const isCurrent = value === currentValue;
|
|
@@ -1911,7 +1604,7 @@ function BossModelSelector({
|
|
|
1911
1604
|
0,
|
|
1912
1605
|
items.findIndex((item) => item.value === currentValue)
|
|
1913
1606
|
);
|
|
1914
|
-
return /* @__PURE__ */ (0,
|
|
1607
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1915
1608
|
BossModelSelectList,
|
|
1916
1609
|
{
|
|
1917
1610
|
items,
|
|
@@ -1924,7 +1617,7 @@ function BossModelSelector({
|
|
|
1924
1617
|
|
|
1925
1618
|
// src/boss-tasks-overlay.tsx
|
|
1926
1619
|
init_esm_shims();
|
|
1927
|
-
var
|
|
1620
|
+
var import_react9 = __toESM(require_react(), 1);
|
|
1928
1621
|
|
|
1929
1622
|
// src/colors.ts
|
|
1930
1623
|
init_esm_shims();
|
|
@@ -1958,7 +1651,7 @@ function projectColor(name) {
|
|
|
1958
1651
|
}
|
|
1959
1652
|
|
|
1960
1653
|
// src/boss-tasks-overlay.tsx
|
|
1961
|
-
var
|
|
1654
|
+
var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
1962
1655
|
function statusGlyph(status) {
|
|
1963
1656
|
switch (status) {
|
|
1964
1657
|
case "done":
|
|
@@ -1981,10 +1674,10 @@ function BossTasksOverlay({
|
|
|
1981
1674
|
const theme = useTheme();
|
|
1982
1675
|
const tasksState = useTasksState();
|
|
1983
1676
|
const tasks = tasksState.tasks;
|
|
1984
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
1985
|
-
const [status, setStatusMsg] = (0,
|
|
1986
|
-
const statusTimer = (0,
|
|
1987
|
-
const showStatus = (0,
|
|
1677
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react9.useState)(0);
|
|
1678
|
+
const [status, setStatusMsg] = (0, import_react9.useState)("");
|
|
1679
|
+
const statusTimer = (0, import_react9.useRef)(null);
|
|
1680
|
+
const showStatus = (0, import_react9.useCallback)((msg) => {
|
|
1988
1681
|
setStatusMsg(msg);
|
|
1989
1682
|
if (statusTimer.current) clearTimeout(statusTimer.current);
|
|
1990
1683
|
statusTimer.current = setTimeout(() => setStatusMsg(""), 2500);
|
|
@@ -1994,7 +1687,7 @@ function BossTasksOverlay({
|
|
|
1994
1687
|
tasks: tasks.filter((t) => t.project === w.name).sort((a, b) => a.createdAt.localeCompare(b.createdAt))
|
|
1995
1688
|
}));
|
|
1996
1689
|
const flatTasks = groupedTasks.flatMap((g) => g.tasks);
|
|
1997
|
-
(0,
|
|
1690
|
+
(0, import_react9.useEffect)(() => {
|
|
1998
1691
|
if (flatTasks.length === 0) {
|
|
1999
1692
|
setSelectedIndex(0);
|
|
2000
1693
|
} else if (selectedIndex >= flatTasks.length) {
|
|
@@ -2054,11 +1747,11 @@ function BossTasksOverlay({
|
|
|
2054
1747
|
const inProgressCount = tasks.filter((t) => t.status === "in_progress").length;
|
|
2055
1748
|
const pendingCount = tasks.filter((t) => t.status === "pending").length;
|
|
2056
1749
|
const blockedCount = tasks.filter((t) => t.status === "blocked").length;
|
|
2057
|
-
return /* @__PURE__ */ (0,
|
|
2058
|
-
/* @__PURE__ */ (0,
|
|
2059
|
-
/* @__PURE__ */ (0,
|
|
2060
|
-
/* @__PURE__ */ (0,
|
|
2061
|
-
/* @__PURE__ */ (0,
|
|
1750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, paddingX: 1, children: [
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { children: [
|
|
1752
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: COLORS.primary, bold: true, children: "Tasks" }),
|
|
1753
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.textDim, children: ` \xB7 ${tasks.length} total \xB7 ` }),
|
|
1754
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2062
1755
|
CountsRow,
|
|
2063
1756
|
{
|
|
2064
1757
|
theme,
|
|
@@ -2069,20 +1762,20 @@ function BossTasksOverlay({
|
|
|
2069
1762
|
}
|
|
2070
1763
|
)
|
|
2071
1764
|
] }),
|
|
2072
|
-
flatTasks.length === 0 && /* @__PURE__ */ (0,
|
|
1765
|
+
flatTasks.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: theme.textDim, children: [
|
|
2073
1766
|
" No tasks yet. Ask the boss to plan some \u2014 e.g. ",
|
|
2074
|
-
/* @__PURE__ */ (0,
|
|
1767
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.text, children: '"plan some work"' }),
|
|
2075
1768
|
"."
|
|
2076
1769
|
] }) }),
|
|
2077
|
-
showingTop && /* @__PURE__ */ (0,
|
|
1770
|
+
showingTop && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.textDim, children: ` \u2191 ${startIdx} more above` }),
|
|
2078
1771
|
groupedTasks.map((group, gIdx) => {
|
|
2079
1772
|
const startInFlat = groupedTasks.slice(0, gIdx).reduce((acc, g) => acc + g.tasks.length, 0);
|
|
2080
1773
|
const visibleInSection = group.tasks.filter((t) => visibleIdSet.has(t.id));
|
|
2081
1774
|
if (visibleInSection.length === 0) return null;
|
|
2082
|
-
return /* @__PURE__ */ (0,
|
|
2083
|
-
/* @__PURE__ */ (0,
|
|
2084
|
-
/* @__PURE__ */ (0,
|
|
2085
|
-
/* @__PURE__ */ (0,
|
|
1775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
|
|
1776
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: projectColor(group.project), bold: true, children: group.project }),
|
|
1778
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.textDim, children: ` \xB7 ${group.tasks.length}` })
|
|
2086
1779
|
] }),
|
|
2087
1780
|
visibleInSection.map((task) => {
|
|
2088
1781
|
const realIdx = startInFlat + group.tasks.indexOf(task);
|
|
@@ -2090,7 +1783,7 @@ function BossTasksOverlay({
|
|
|
2090
1783
|
const prefix = isSelected ? "\u276F " : " ";
|
|
2091
1784
|
const glyph = statusGlyph(task.status);
|
|
2092
1785
|
const color2 = isSelected ? theme.primary : task.status === "done" ? theme.success : task.status === "in_progress" ? theme.warning : task.status === "blocked" ? theme.error : theme.text;
|
|
2093
|
-
return /* @__PURE__ */ (0,
|
|
1786
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: color2, bold: isSelected, children: [
|
|
2094
1787
|
prefix,
|
|
2095
1788
|
"[",
|
|
2096
1789
|
glyph,
|
|
@@ -2100,16 +1793,16 @@ function BossTasksOverlay({
|
|
|
2100
1793
|
})
|
|
2101
1794
|
] }, group.project);
|
|
2102
1795
|
}),
|
|
2103
|
-
showingBottom && /* @__PURE__ */ (0,
|
|
2104
|
-
status && /* @__PURE__ */ (0,
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
1796
|
+
showingBottom && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.textDim, children: ` \u2193 ${flatTasks.length - endIdx} more below` }),
|
|
1797
|
+
status && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.success, children: " " + status }) }),
|
|
1798
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: theme.textDim, children: [
|
|
1799
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.primary, children: "\u2191\u2193" }),
|
|
2107
1800
|
" move \xB7 (",
|
|
2108
|
-
/* @__PURE__ */ (0,
|
|
1801
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.primary, children: "d" }),
|
|
2109
1802
|
")elete \xB7 (",
|
|
2110
|
-
/* @__PURE__ */ (0,
|
|
1803
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.primary, children: "r" }),
|
|
2111
1804
|
")un pending \xB7 ",
|
|
2112
|
-
/* @__PURE__ */ (0,
|
|
1805
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.primary, children: "ESC" }),
|
|
2113
1806
|
" close"
|
|
2114
1807
|
] }) })
|
|
2115
1808
|
] });
|
|
@@ -2121,24 +1814,24 @@ function CountsRow({
|
|
|
2121
1814
|
pending,
|
|
2122
1815
|
blocked
|
|
2123
1816
|
}) {
|
|
2124
|
-
return /* @__PURE__ */ (0,
|
|
2125
|
-
/* @__PURE__ */ (0,
|
|
1817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { children: [
|
|
1818
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: theme.success, children: [
|
|
2126
1819
|
done,
|
|
2127
1820
|
" done"
|
|
2128
1821
|
] }),
|
|
2129
|
-
/* @__PURE__ */ (0,
|
|
2130
|
-
/* @__PURE__ */ (0,
|
|
1822
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.textDim, children: " \xB7 " }),
|
|
1823
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: theme.warning, children: [
|
|
2131
1824
|
active,
|
|
2132
1825
|
" active"
|
|
2133
1826
|
] }),
|
|
2134
|
-
/* @__PURE__ */ (0,
|
|
2135
|
-
/* @__PURE__ */ (0,
|
|
1827
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.textDim, children: " \xB7 " }),
|
|
1828
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: theme.text, children: [
|
|
2136
1829
|
pending,
|
|
2137
1830
|
" pending"
|
|
2138
1831
|
] }),
|
|
2139
|
-
blocked > 0 && /* @__PURE__ */ (0,
|
|
2140
|
-
/* @__PURE__ */ (0,
|
|
2141
|
-
/* @__PURE__ */ (0,
|
|
1832
|
+
blocked > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1833
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { color: theme.textDim, children: " \xB7 " }),
|
|
1834
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: theme.error, children: [
|
|
2142
1835
|
blocked,
|
|
2143
1836
|
" blocked"
|
|
2144
1837
|
] })
|
|
@@ -2148,8 +1841,8 @@ function CountsRow({
|
|
|
2148
1841
|
|
|
2149
1842
|
// src/boss-worker-status-row.tsx
|
|
2150
1843
|
init_esm_shims();
|
|
2151
|
-
var
|
|
2152
|
-
var
|
|
1844
|
+
var import_react10 = __toESM(require_react(), 1);
|
|
1845
|
+
var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
|
|
2153
1846
|
var SHIMMER_WIDTH = 3;
|
|
2154
1847
|
function formatWorkerElapsed(ms) {
|
|
2155
1848
|
const total = Math.floor(ms / 1e3);
|
|
@@ -2168,9 +1861,9 @@ function ShimmerName({
|
|
|
2168
1861
|
}) {
|
|
2169
1862
|
const cycle = name.length + SHIMMER_WIDTH * 2;
|
|
2170
1863
|
const shimmerPos = tick % cycle - SHIMMER_WIDTH;
|
|
2171
|
-
return /* @__PURE__ */ (0,
|
|
1864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { children: name.split("").map((ch, i) => {
|
|
2172
1865
|
const isBright = Math.abs(i - shimmerPos) <= SHIMMER_WIDTH;
|
|
2173
|
-
return /* @__PURE__ */ (0,
|
|
1866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: color2, bold: isBright, dimColor: !isBright, children: ch }, i);
|
|
2174
1867
|
}) });
|
|
2175
1868
|
}
|
|
2176
1869
|
function BossWorkerStatusRow({
|
|
@@ -2191,9 +1884,9 @@ function BossWorkerStatusRow({
|
|
|
2191
1884
|
const projectHue = projectColor(w.name);
|
|
2192
1885
|
const elapsed = w.workStartedAt ? formatWorkerElapsed(now - w.workStartedAt) : null;
|
|
2193
1886
|
slots.push(
|
|
2194
|
-
/* @__PURE__ */ (0,
|
|
2195
|
-
/* @__PURE__ */ (0,
|
|
2196
|
-
elapsed && /* @__PURE__ */ (0,
|
|
1887
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react10.default.Fragment, { children: [
|
|
1888
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShimmerName, { name: w.name, color: projectHue, tick }),
|
|
1889
|
+
elapsed && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { color: theme.textDim, children: [
|
|
2197
1890
|
" ",
|
|
2198
1891
|
elapsed
|
|
2199
1892
|
] })
|
|
@@ -2202,7 +1895,7 @@ function BossWorkerStatusRow({
|
|
|
2202
1895
|
}
|
|
2203
1896
|
for (const w of errored) {
|
|
2204
1897
|
slots.push(
|
|
2205
|
-
/* @__PURE__ */ (0,
|
|
1898
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react10.default.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { color: theme.error, children: [
|
|
2206
1899
|
"\u2717 ",
|
|
2207
1900
|
w.name
|
|
2208
1901
|
] }) }, `e-${w.name}`)
|
|
@@ -2210,23 +1903,23 @@ function BossWorkerStatusRow({
|
|
|
2210
1903
|
}
|
|
2211
1904
|
if (idleCount > 0) {
|
|
2212
1905
|
slots.push(
|
|
2213
|
-
/* @__PURE__ */ (0,
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react10.default.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { color: theme.textDim, children: [
|
|
2214
1907
|
"\u25CB ",
|
|
2215
1908
|
idleCount,
|
|
2216
1909
|
" idle"
|
|
2217
1910
|
] }) }, "idle")
|
|
2218
1911
|
);
|
|
2219
1912
|
}
|
|
2220
|
-
return /* @__PURE__ */ (0,
|
|
2221
|
-
anyWorking && /* @__PURE__ */ (0,
|
|
2222
|
-
/* @__PURE__ */ (0,
|
|
2223
|
-
slots.map((slot, i) => /* @__PURE__ */ (0,
|
|
2224
|
-
i > 0 && /* @__PURE__ */ (0,
|
|
1913
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { paddingX: 1, width: columns, flexShrink: 1, children: [
|
|
1914
|
+
anyWorking && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AnimationActiveSentinel, {}),
|
|
1915
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { wrap: "truncate", children: [
|
|
1916
|
+
slots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react10.default.Fragment, { children: [
|
|
1917
|
+
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: theme.border, children: " \u2502 " }),
|
|
2225
1918
|
slot
|
|
2226
1919
|
] }, i)),
|
|
2227
|
-
pendingMessages > 0 && /* @__PURE__ */ (0,
|
|
2228
|
-
/* @__PURE__ */ (0,
|
|
2229
|
-
/* @__PURE__ */ (0,
|
|
1920
|
+
pendingMessages > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: theme.textDim, children: " " }),
|
|
1922
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { color: theme.warning, children: [
|
|
2230
1923
|
pendingMessages,
|
|
2231
1924
|
" message",
|
|
2232
1925
|
pendingMessages === 1 ? "" : "s",
|
|
@@ -2239,7 +1932,7 @@ function BossWorkerStatusRow({
|
|
|
2239
1932
|
|
|
2240
1933
|
// src/radio-picker.tsx
|
|
2241
1934
|
init_esm_shims();
|
|
2242
|
-
var
|
|
1935
|
+
var import_react11 = __toESM(require_react(), 1);
|
|
2243
1936
|
|
|
2244
1937
|
// src/radio.ts
|
|
2245
1938
|
init_esm_shims();
|
|
@@ -2407,7 +2100,7 @@ function buildInstallHint() {
|
|
|
2407
2100
|
}
|
|
2408
2101
|
|
|
2409
2102
|
// src/radio-picker.tsx
|
|
2410
|
-
var
|
|
2103
|
+
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
2411
2104
|
function RadioPicker({
|
|
2412
2105
|
currentStationId: currentStationId2,
|
|
2413
2106
|
onSelect,
|
|
@@ -2429,7 +2122,7 @@ function RadioPicker({
|
|
|
2429
2122
|
0,
|
|
2430
2123
|
items.findIndex((i) => i.value === (currentStationId2 ?? "off"))
|
|
2431
2124
|
);
|
|
2432
|
-
return /* @__PURE__ */ (0,
|
|
2125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2433
2126
|
SelectList,
|
|
2434
2127
|
{
|
|
2435
2128
|
items,
|
|
@@ -2442,7 +2135,7 @@ function RadioPicker({
|
|
|
2442
2135
|
}
|
|
2443
2136
|
|
|
2444
2137
|
// src/boss-chat-screen.tsx
|
|
2445
|
-
var
|
|
2138
|
+
var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
|
|
2446
2139
|
function BossChatScreen({
|
|
2447
2140
|
boss,
|
|
2448
2141
|
columns,
|
|
@@ -2483,12 +2176,12 @@ function BossChatScreen({
|
|
|
2483
2176
|
formatDuration
|
|
2484
2177
|
}) {
|
|
2485
2178
|
if (overlay === "tasks") {
|
|
2486
|
-
return /* @__PURE__ */ (0,
|
|
2179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChatLayout, { columns, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BossTasksOverlay, { boss, workers, onClose: onCloseOverlay }) });
|
|
2487
2180
|
}
|
|
2488
|
-
return /* @__PURE__ */ (0,
|
|
2181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(ChatLayout, { columns, children: [
|
|
2489
2182
|
livePane,
|
|
2490
|
-
/* @__PURE__ */ (0,
|
|
2491
|
-
/* @__PURE__ */ (0,
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(ChatControls, { controlsRef, children: [
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2492
2185
|
ChatInputStack,
|
|
2493
2186
|
{
|
|
2494
2187
|
columns,
|
|
@@ -2496,6 +2189,7 @@ function BossChatScreen({
|
|
|
2496
2189
|
statusSlotVisible,
|
|
2497
2190
|
activityVisible,
|
|
2498
2191
|
stallStatusVisible,
|
|
2192
|
+
liveToolFeed: [],
|
|
2499
2193
|
doneStatus,
|
|
2500
2194
|
activityPhase: state.activityPhase,
|
|
2501
2195
|
elapsedMs,
|
|
@@ -2515,7 +2209,7 @@ function BossChatScreen({
|
|
|
2515
2209
|
formatDuration
|
|
2516
2210
|
}
|
|
2517
2211
|
),
|
|
2518
|
-
/* @__PURE__ */ (0,
|
|
2212
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2519
2213
|
InputArea,
|
|
2520
2214
|
{
|
|
2521
2215
|
onSubmit,
|
|
@@ -2530,7 +2224,7 @@ function BossChatScreen({
|
|
|
2530
2224
|
onShiftTab
|
|
2531
2225
|
}
|
|
2532
2226
|
),
|
|
2533
|
-
overlay === "model-boss" || overlay === "model-workers" ? /* @__PURE__ */ (0,
|
|
2227
|
+
overlay === "model-boss" || overlay === "model-workers" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2534
2228
|
BossModelSelector,
|
|
2535
2229
|
{
|
|
2536
2230
|
onSelect: onModelSelect,
|
|
@@ -2538,15 +2232,15 @@ function BossChatScreen({
|
|
|
2538
2232
|
currentModel: overlay === "model-boss" ? state.bossModel : state.workerModel,
|
|
2539
2233
|
currentProvider: overlay === "model-boss" ? state.bossProvider : state.workerProvider
|
|
2540
2234
|
}
|
|
2541
|
-
) : overlay === "radio" ? /* @__PURE__ */ (0,
|
|
2235
|
+
) : overlay === "radio" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2542
2236
|
RadioPicker,
|
|
2543
2237
|
{
|
|
2544
2238
|
currentStationId: currentRadio,
|
|
2545
2239
|
onCancel: onCloseOverlay,
|
|
2546
2240
|
onSelect: onRadioSelect
|
|
2547
2241
|
}
|
|
2548
|
-
) : /* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2242
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
2243
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2550
2244
|
BossFooter,
|
|
2551
2245
|
{
|
|
2552
2246
|
bossModel,
|
|
@@ -2559,7 +2253,7 @@ function BossChatScreen({
|
|
|
2559
2253
|
scope: state.scope
|
|
2560
2254
|
}
|
|
2561
2255
|
),
|
|
2562
|
-
!state.exitPending && /* @__PURE__ */ (0,
|
|
2256
|
+
!state.exitPending && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(BossWorkerStatusRow, { workers, pendingMessages })
|
|
2563
2257
|
] })
|
|
2564
2258
|
] })
|
|
2565
2259
|
] });
|
|
@@ -2636,7 +2330,7 @@ function buildHelpText() {
|
|
|
2636
2330
|
|
|
2637
2331
|
// src/boss-transcript-rows.tsx
|
|
2638
2332
|
init_esm_shims();
|
|
2639
|
-
var
|
|
2333
|
+
var import_react13 = __toESM(require_react(), 1);
|
|
2640
2334
|
|
|
2641
2335
|
// src/boss-spacing.ts
|
|
2642
2336
|
init_esm_shims();
|
|
@@ -2752,7 +2446,7 @@ var bossToolFormatters = {
|
|
|
2752
2446
|
};
|
|
2753
2447
|
|
|
2754
2448
|
// src/boss-transcript-rows.tsx
|
|
2755
|
-
var
|
|
2449
|
+
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
2756
2450
|
function getBossTranscriptMarginTop({
|
|
2757
2451
|
row,
|
|
2758
2452
|
previousRow
|
|
@@ -2771,26 +2465,26 @@ function BossTranscriptRow({
|
|
|
2771
2465
|
previousRow
|
|
2772
2466
|
}) {
|
|
2773
2467
|
if (row.kind === "banner") {
|
|
2774
|
-
return /* @__PURE__ */ (0,
|
|
2468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(BossBanner, { subtitle: "Orchestrator", showShortcuts: true }) });
|
|
2775
2469
|
}
|
|
2776
2470
|
const marginTop = getBossTranscriptMarginTop({ row, previousRow });
|
|
2777
|
-
const renderWithSpacing = (node) => /* @__PURE__ */ (0,
|
|
2778
|
-
if (row.kind === "user") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2779
|
-
if (row.kind === "assistant") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2780
|
-
if (row.kind === "tool_start") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2781
|
-
if (row.kind === "tool_done") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2782
|
-
if (row.kind === "tool_group") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2783
|
-
if (row.kind === "worker_event") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2784
|
-
if (row.kind === "worker_error") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2471
|
+
const renderWithSpacing = (node) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TranscriptItemFrame, { marginTop, children: node });
|
|
2472
|
+
if (row.kind === "user") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UserMessage, { text: row.text }));
|
|
2473
|
+
if (row.kind === "assistant") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AssistantRow, { item: row }));
|
|
2474
|
+
if (row.kind === "tool_start") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolStartHistoryRow, { item: row }));
|
|
2475
|
+
if (row.kind === "tool_done") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolHistoryRow, { item: row }));
|
|
2476
|
+
if (row.kind === "tool_group") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolGroupRow, { item: row }));
|
|
2477
|
+
if (row.kind === "worker_event") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(WorkerEventRow, { item: row }));
|
|
2478
|
+
if (row.kind === "worker_error") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(WorkerErrorRow, { item: row }));
|
|
2785
2479
|
if (row.kind === "info") {
|
|
2786
|
-
return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2480
|
+
return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(InfoRow, { text: row.text, level: row.level ?? "info" }));
|
|
2787
2481
|
}
|
|
2788
|
-
if (row.kind === "task_dispatch") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2789
|
-
if (row.kind === "update_notice") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2790
|
-
if (row.kind === "compacting") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2482
|
+
if (row.kind === "task_dispatch") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TaskDispatchRow, { tasks: row.tasks }));
|
|
2483
|
+
if (row.kind === "update_notice") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpdateNoticeRow, { text: row.text }));
|
|
2484
|
+
if (row.kind === "compacting") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CompactionSpinner, { staticDisplay: true }));
|
|
2791
2485
|
if (row.kind === "compacted") {
|
|
2792
2486
|
return renderWithSpacing(
|
|
2793
|
-
/* @__PURE__ */ (0,
|
|
2487
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2794
2488
|
CompactionDone,
|
|
2795
2489
|
{
|
|
2796
2490
|
originalCount: row.originalCount,
|
|
@@ -2801,13 +2495,13 @@ function BossTranscriptRow({
|
|
|
2801
2495
|
)
|
|
2802
2496
|
);
|
|
2803
2497
|
}
|
|
2804
|
-
if (row.kind === "stopped") return renderWithSpacing(/* @__PURE__ */ (0,
|
|
2498
|
+
if (row.kind === "stopped") return renderWithSpacing(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(InfoRow, { text: row.text, level: "warning" }));
|
|
2805
2499
|
return null;
|
|
2806
2500
|
}
|
|
2807
2501
|
function UpdateNoticeRow({ text }) {
|
|
2808
|
-
return /* @__PURE__ */ (0,
|
|
2809
|
-
/* @__PURE__ */ (0,
|
|
2810
|
-
/* @__PURE__ */ (0,
|
|
2502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexShrink: 1, borderStyle: "round", borderColor: COLORS.accent, paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { wrap: "wrap", children: [
|
|
2503
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: COLORS.accent, bold: true, children: "\u2728 " }),
|
|
2504
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: COLORS.primary, bold: true, children: text })
|
|
2811
2505
|
] }) });
|
|
2812
2506
|
}
|
|
2813
2507
|
function TaskDispatchRow({
|
|
@@ -2815,10 +2509,10 @@ function TaskDispatchRow({
|
|
|
2815
2509
|
}) {
|
|
2816
2510
|
const theme = useTheme();
|
|
2817
2511
|
const count = tasks.length;
|
|
2818
|
-
return /* @__PURE__ */ (0,
|
|
2819
|
-
/* @__PURE__ */ (0,
|
|
2820
|
-
/* @__PURE__ */ (0,
|
|
2821
|
-
/* @__PURE__ */ (0,
|
|
2512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, children: [
|
|
2513
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
|
|
2514
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: COLORS.primary, bold: true, children: "\u23FA " }),
|
|
2515
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { color: theme.text, bold: true, children: [
|
|
2822
2516
|
"Running ",
|
|
2823
2517
|
count,
|
|
2824
2518
|
" task",
|
|
@@ -2826,11 +2520,11 @@ function TaskDispatchRow({
|
|
|
2826
2520
|
":"
|
|
2827
2521
|
] })
|
|
2828
2522
|
] }),
|
|
2829
|
-
tasks.map((t, i) => /* @__PURE__ */ (0,
|
|
2830
|
-
/* @__PURE__ */ (0,
|
|
2831
|
-
/* @__PURE__ */ (0,
|
|
2832
|
-
/* @__PURE__ */ (0,
|
|
2833
|
-
/* @__PURE__ */ (0,
|
|
2523
|
+
tasks.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
|
|
2524
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: theme.textDim, children: " \u2022 " }),
|
|
2525
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: projectColor(t.project), bold: true, children: t.project }),
|
|
2526
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: theme.textDim, children: ": " }),
|
|
2527
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: theme.text, children: t.title })
|
|
2834
2528
|
] }, `${t.project}-${i}`))
|
|
2835
2529
|
] });
|
|
2836
2530
|
}
|
|
@@ -2857,12 +2551,12 @@ function highlightShortcuts(text) {
|
|
|
2857
2551
|
);
|
|
2858
2552
|
}
|
|
2859
2553
|
function AssistantRow({ item }) {
|
|
2860
|
-
return /* @__PURE__ */ (0,
|
|
2554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AssistantMessage, { text: highlightShortcuts(item.text), renderMarkdown: true });
|
|
2861
2555
|
}
|
|
2862
2556
|
function ToolStartHistoryRow({
|
|
2863
2557
|
item
|
|
2864
2558
|
}) {
|
|
2865
|
-
return /* @__PURE__ */ (0,
|
|
2559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2866
2560
|
ToolExecution,
|
|
2867
2561
|
{
|
|
2868
2562
|
status: "running",
|
|
@@ -2873,10 +2567,10 @@ function ToolStartHistoryRow({
|
|
|
2873
2567
|
);
|
|
2874
2568
|
}
|
|
2875
2569
|
function ToolGroupRow({ item }) {
|
|
2876
|
-
return /* @__PURE__ */ (0,
|
|
2570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolGroupExecution, { tools: item.tools, summaryRenderers: bossToolGroupRenderers });
|
|
2877
2571
|
}
|
|
2878
2572
|
function ToolHistoryRow({ item }) {
|
|
2879
|
-
return /* @__PURE__ */ (0,
|
|
2573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2880
2574
|
ToolExecution,
|
|
2881
2575
|
{
|
|
2882
2576
|
status: "done",
|
|
@@ -2918,41 +2612,41 @@ function WorkerEventRow({ item }) {
|
|
|
2918
2612
|
const grade = parseStatusGrade(item.finalText);
|
|
2919
2613
|
const loaderStatus = grade === "BLOCKED" || failedCount > 0 ? "error" : grade === "UNVERIFIED" || grade === "PARTIAL" ? "queued" : "done";
|
|
2920
2614
|
const headerColor = loaderStatus === "error" ? theme.toolError : projectColor(item.project);
|
|
2921
|
-
return /* @__PURE__ */ (0,
|
|
2922
|
-
/* @__PURE__ */ (0,
|
|
2923
|
-
/* @__PURE__ */ (0,
|
|
2924
|
-
/* @__PURE__ */ (0,
|
|
2925
|
-
/* @__PURE__ */ (0,
|
|
2926
|
-
grade && /* @__PURE__ */ (0,
|
|
2927
|
-
/* @__PURE__ */ (0,
|
|
2928
|
-
/* @__PURE__ */ (0,
|
|
2615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "row", children: [
|
|
2616
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolUseLoader, { status: loaderStatus }),
|
|
2617
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { wrap: "wrap", children: [
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: headerColor, bold: true, children: item.project }),
|
|
2619
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: theme.text, children: ` turn ${item.turnIndex}` }),
|
|
2620
|
+
grade && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
2621
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: theme.textDim, children: " \xB7 " }),
|
|
2622
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: statusGradeColor(grade, theme), bold: true, children: grade })
|
|
2929
2623
|
] })
|
|
2930
2624
|
] }) })
|
|
2931
2625
|
] });
|
|
2932
2626
|
}
|
|
2933
2627
|
function WorkerErrorRow({ item }) {
|
|
2934
2628
|
const theme = useTheme();
|
|
2935
|
-
return /* @__PURE__ */ (0,
|
|
2936
|
-
/* @__PURE__ */ (0,
|
|
2937
|
-
/* @__PURE__ */ (0,
|
|
2938
|
-
/* @__PURE__ */ (0,
|
|
2939
|
-
/* @__PURE__ */ (0,
|
|
2940
|
-
/* @__PURE__ */ (0,
|
|
2629
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
2630
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "row", children: [
|
|
2631
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolUseLoader, { status: "error" }),
|
|
2632
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { wrap: "wrap", children: [
|
|
2633
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: theme.toolError, bold: true, children: item.project }),
|
|
2634
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: theme.textDim, children: " worker error" })
|
|
2941
2635
|
] }) })
|
|
2942
2636
|
] }),
|
|
2943
|
-
/* @__PURE__ */ (0,
|
|
2637
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MessageResponse, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: theme.error, wrap: "wrap", children: item.message }) })
|
|
2944
2638
|
] });
|
|
2945
2639
|
}
|
|
2946
2640
|
function InfoRow({
|
|
2947
2641
|
text,
|
|
2948
2642
|
level
|
|
2949
2643
|
}) {
|
|
2950
|
-
if (level === "info") return /* @__PURE__ */ (0,
|
|
2644
|
+
if (level === "info") return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AssistantMessage, { text });
|
|
2951
2645
|
const theme = useTheme();
|
|
2952
2646
|
const color2 = level === "error" ? theme.error : theme.warning;
|
|
2953
|
-
return /* @__PURE__ */ (0,
|
|
2954
|
-
/* @__PURE__ */ (0,
|
|
2955
|
-
/* @__PURE__ */ (0,
|
|
2647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "row", children: [
|
|
2648
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolUseLoader, { status: level === "error" ? "error" : "queued" }),
|
|
2649
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: color2, wrap: "wrap", children: text }) })
|
|
2956
2650
|
] });
|
|
2957
2651
|
}
|
|
2958
2652
|
function BossStreamingTurnView({
|
|
@@ -2979,11 +2673,11 @@ function BossStreamingTurnView({
|
|
|
2979
2673
|
spacingKinds: BOSS_SPACING_KINDS,
|
|
2980
2674
|
compactBoundaries: BOSS_COMPACT_BOUNDARIES
|
|
2981
2675
|
}) ? 1 : 0;
|
|
2982
|
-
return /* @__PURE__ */ (0,
|
|
2676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2983
2677
|
ChatLivePane,
|
|
2984
2678
|
{
|
|
2985
2679
|
liveItems: visibleLiveItems,
|
|
2986
|
-
renderItem: (_item, index) => /* @__PURE__ */ (0,
|
|
2680
|
+
renderItem: (_item, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2987
2681
|
BossTranscriptRow,
|
|
2988
2682
|
{
|
|
2989
2683
|
row: visibleLiveItems[index],
|
|
@@ -3305,176 +2999,23 @@ function renderRoundNoticeBox(lines, context, borderColor) {
|
|
|
3305
2999
|
|
|
3306
3000
|
// src/auto-update.ts
|
|
3307
3001
|
init_esm_shims();
|
|
3308
|
-
import { spawn as spawn2 } from "child_process";
|
|
3309
|
-
import fs4 from "fs";
|
|
3310
3002
|
import path4 from "path";
|
|
3311
3003
|
import os2 from "os";
|
|
3312
|
-
var
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
const raw = fs4.readFileSync(getStateFilePath(), "utf-8");
|
|
3322
|
-
return JSON.parse(raw);
|
|
3323
|
-
} catch {
|
|
3324
|
-
return null;
|
|
3325
|
-
}
|
|
3326
|
-
}
|
|
3327
|
-
function writeState(state) {
|
|
3328
|
-
try {
|
|
3329
|
-
const dir = path4.dirname(getStateFilePath());
|
|
3330
|
-
fs4.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
3331
|
-
fs4.writeFileSync(getStateFilePath(), JSON.stringify(state));
|
|
3332
|
-
} catch {
|
|
3333
|
-
}
|
|
3334
|
-
}
|
|
3335
|
-
function compareVersions(a, b) {
|
|
3336
|
-
const pa = a.split(".").map(Number);
|
|
3337
|
-
const pb = b.split(".").map(Number);
|
|
3338
|
-
for (let i = 0; i < 3; i++) {
|
|
3339
|
-
const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
3340
|
-
if (diff !== 0) return diff;
|
|
3341
|
-
}
|
|
3342
|
-
return 0;
|
|
3343
|
-
}
|
|
3344
|
-
function detectInstallInfo() {
|
|
3345
|
-
const scriptPath = (process.argv[1] ?? "").replace(/\\/g, "/");
|
|
3346
|
-
if (scriptPath.includes("/_npx/")) {
|
|
3347
|
-
return { packageManager: "unknown" /* UNKNOWN */, updateCommand: null };
|
|
3348
|
-
}
|
|
3349
|
-
if (scriptPath.includes("/.pnpm") || scriptPath.includes("/pnpm/global")) {
|
|
3350
|
-
return {
|
|
3351
|
-
packageManager: "pnpm" /* PNPM */,
|
|
3352
|
-
updateCommand: `pnpm add -g ${PACKAGE_NAME}@latest`
|
|
3353
|
-
};
|
|
3354
|
-
}
|
|
3355
|
-
if (scriptPath.includes("/.yarn/") || scriptPath.includes("/yarn/global")) {
|
|
3356
|
-
return {
|
|
3357
|
-
packageManager: "yarn" /* YARN */,
|
|
3358
|
-
updateCommand: `yarn global add ${PACKAGE_NAME}@latest`
|
|
3359
|
-
};
|
|
3360
|
-
}
|
|
3361
|
-
return {
|
|
3362
|
-
packageManager: "npm" /* NPM */,
|
|
3363
|
-
updateCommand: `npm install -g ${PACKAGE_NAME}@latest`
|
|
3364
|
-
};
|
|
3365
|
-
}
|
|
3366
|
-
async function fetchLatestVersion() {
|
|
3367
|
-
try {
|
|
3368
|
-
const controller = new AbortController();
|
|
3369
|
-
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
3370
|
-
const response = await fetch(REGISTRY_URL, { signal: controller.signal });
|
|
3371
|
-
clearTimeout(timeout);
|
|
3372
|
-
const data = await response.json();
|
|
3373
|
-
const version = data.version?.trim();
|
|
3374
|
-
return version && /^\d+\.\d+\.\d+/.test(version) ? version : null;
|
|
3375
|
-
} catch {
|
|
3376
|
-
return null;
|
|
3377
|
-
}
|
|
3378
|
-
}
|
|
3379
|
-
function performUpdateInBackground(command) {
|
|
3380
|
-
try {
|
|
3381
|
-
const parts = command.split(" ");
|
|
3382
|
-
const child = spawn2(parts[0], parts.slice(1), {
|
|
3383
|
-
detached: true,
|
|
3384
|
-
stdio: "ignore",
|
|
3385
|
-
env: { ...process.env, npm_config_loglevel: "silent" }
|
|
3386
|
-
});
|
|
3387
|
-
child.unref();
|
|
3388
|
-
} catch {
|
|
3389
|
-
}
|
|
3390
|
-
}
|
|
3391
|
-
function checkAndAutoUpdate(currentVersion) {
|
|
3392
|
-
try {
|
|
3393
|
-
const state = readState();
|
|
3394
|
-
let message = null;
|
|
3395
|
-
if (state?.updatePending && state.latestVersion) {
|
|
3396
|
-
if (compareVersions(state.latestVersion, currentVersion) > 0) {
|
|
3397
|
-
const info = detectInstallInfo();
|
|
3398
|
-
if (info.updateCommand) {
|
|
3399
|
-
performUpdateInBackground(info.updateCommand);
|
|
3400
|
-
message = `Ken just shipped ${state.latestVersion}! Installing in the background \u2014 takes effect next launch.`;
|
|
3401
|
-
writeState({
|
|
3402
|
-
...state,
|
|
3403
|
-
lastCheckedAt: Date.now(),
|
|
3404
|
-
updatePending: false,
|
|
3405
|
-
lastUpdateAttempt: Date.now()
|
|
3406
|
-
});
|
|
3407
|
-
}
|
|
3408
|
-
} else {
|
|
3409
|
-
writeState({ ...state, updatePending: false });
|
|
3410
|
-
}
|
|
3411
|
-
}
|
|
3412
|
-
const shouldCheck = !state || Date.now() - state.lastCheckedAt > CHECK_INTERVAL_MS;
|
|
3413
|
-
if (shouldCheck) scheduleBackgroundCheck(currentVersion);
|
|
3414
|
-
return message;
|
|
3415
|
-
} catch {
|
|
3416
|
-
return null;
|
|
3417
|
-
}
|
|
3418
|
-
}
|
|
3419
|
-
function getPendingUpdate(currentVersion) {
|
|
3420
|
-
try {
|
|
3421
|
-
const state = readState();
|
|
3422
|
-
if (!state?.latestVersion) return null;
|
|
3423
|
-
if (compareVersions(state.latestVersion, currentVersion) <= 0) return null;
|
|
3424
|
-
return { latestVersion: state.latestVersion };
|
|
3425
|
-
} catch {
|
|
3426
|
-
return null;
|
|
3427
|
-
}
|
|
3428
|
-
}
|
|
3429
|
-
function scheduleBackgroundCheck(currentVersion) {
|
|
3430
|
-
fetchLatestVersion().then((latestVersion) => {
|
|
3431
|
-
const newState = {
|
|
3432
|
-
lastCheckedAt: Date.now(),
|
|
3433
|
-
latestVersion: latestVersion ?? void 0,
|
|
3434
|
-
updatePending: false
|
|
3435
|
-
};
|
|
3436
|
-
if (latestVersion && compareVersions(latestVersion, currentVersion) > 0) {
|
|
3437
|
-
newState.updatePending = true;
|
|
3438
|
-
}
|
|
3439
|
-
writeState(newState);
|
|
3440
|
-
}).catch(() => {
|
|
3441
|
-
});
|
|
3442
|
-
}
|
|
3443
|
-
var periodicTimer = null;
|
|
3444
|
-
function startPeriodicUpdateCheck(currentVersion, onUpdate) {
|
|
3445
|
-
if (periodicTimer) return;
|
|
3446
|
-
periodicTimer = setInterval(() => {
|
|
3447
|
-
fetchLatestVersion().then((latestVersion) => {
|
|
3448
|
-
if (!latestVersion) return;
|
|
3449
|
-
if (compareVersions(latestVersion, currentVersion) <= 0) return;
|
|
3450
|
-
const info = detectInstallInfo();
|
|
3451
|
-
if (!info.updateCommand) return;
|
|
3452
|
-
writeState({
|
|
3453
|
-
lastCheckedAt: Date.now(),
|
|
3454
|
-
latestVersion,
|
|
3455
|
-
updatePending: true
|
|
3456
|
-
});
|
|
3457
|
-
onUpdate(
|
|
3458
|
-
`Ken just pushed a fresh update \u2014 ${currentVersion} \u2192 ${latestVersion}! Restart ggboss to grab it (or run ${info.updateCommand} if you can't wait).`
|
|
3459
|
-
);
|
|
3460
|
-
stopPeriodicUpdateCheck();
|
|
3461
|
-
}).catch(() => {
|
|
3462
|
-
});
|
|
3463
|
-
}, CHECK_INTERVAL_MS);
|
|
3464
|
-
periodicTimer.unref();
|
|
3465
|
-
}
|
|
3466
|
-
function stopPeriodicUpdateCheck() {
|
|
3467
|
-
if (periodicTimer) {
|
|
3468
|
-
clearInterval(periodicTimer);
|
|
3469
|
-
periodicTimer = null;
|
|
3470
|
-
}
|
|
3471
|
-
}
|
|
3004
|
+
var updater = createAutoUpdater({
|
|
3005
|
+
packageName: "@kenkaiiii/gg-boss",
|
|
3006
|
+
stateFilePath: () => path4.join(os2.homedir(), ".gg", "boss", "update-state.json"),
|
|
3007
|
+
periodicMessage: ({ currentVersion, latestVersion, updateCommand }) => `Ken just pushed a fresh update \u2014 ${currentVersion} \u2192 ${latestVersion}! Restart ggboss to grab it (or run ${updateCommand} if you can't wait).`
|
|
3008
|
+
});
|
|
3009
|
+
var checkAndAutoUpdate = updater.checkAndAutoUpdate;
|
|
3010
|
+
var getPendingUpdate = updater.getPendingUpdate;
|
|
3011
|
+
var startPeriodicUpdateCheck = updater.startPeriodicUpdateCheck;
|
|
3012
|
+
var stopPeriodicUpdateCheck = updater.stopPeriodicUpdateCheck;
|
|
3472
3013
|
|
|
3473
3014
|
// src/orchestrator-app.tsx
|
|
3474
|
-
var
|
|
3015
|
+
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
3475
3016
|
function BossApp(props) {
|
|
3476
3017
|
const theme = loadTheme("dark");
|
|
3477
|
-
return /* @__PURE__ */ (0,
|
|
3018
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TerminalSizeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ThemeContext.Provider, { value: theme, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AnimationProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BossAppInner, { ...props }) }) }) });
|
|
3478
3019
|
}
|
|
3479
3020
|
function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
3480
3021
|
const state = useBossState();
|
|
@@ -3482,19 +3023,19 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3482
3023
|
const { exit } = use_app_default();
|
|
3483
3024
|
const { stdout, write: writeStdout } = use_stdout_default();
|
|
3484
3025
|
const { columns, rows } = useTerminalSize();
|
|
3485
|
-
const runStartRef = (0,
|
|
3026
|
+
const runStartRef = (0, import_react14.useRef)(null);
|
|
3486
3027
|
runStartRef.current = state.runStartMs;
|
|
3487
|
-
const charCountRef = (0,
|
|
3028
|
+
const charCountRef = (0, import_react14.useRef)(0);
|
|
3488
3029
|
charCountRef.current = state.streaming?.text.length ?? 0;
|
|
3489
|
-
const realTokensAccumRef = (0,
|
|
3030
|
+
const realTokensAccumRef = (0, import_react14.useRef)(0);
|
|
3490
3031
|
realTokensAccumRef.current = state.bossInputTokens;
|
|
3491
|
-
const [lastUserMessage, setLastUserMessage] = (0,
|
|
3032
|
+
const [lastUserMessage, setLastUserMessage] = (0, import_react14.useState)("");
|
|
3492
3033
|
const overlay = state.overlay;
|
|
3493
|
-
const [currentRadio, setCurrentRadio] = (0,
|
|
3494
|
-
const [updatePending, setUpdatePending] = (0,
|
|
3034
|
+
const [currentRadio, setCurrentRadio] = (0, import_react14.useState)(() => getCurrentStation());
|
|
3035
|
+
const [updatePending, setUpdatePending] = (0, import_react14.useState)(
|
|
3495
3036
|
() => getPendingUpdate(VERSION) !== null
|
|
3496
3037
|
);
|
|
3497
|
-
(0,
|
|
3038
|
+
(0, import_react14.useEffect)(() => {
|
|
3498
3039
|
startPeriodicUpdateCheck(VERSION, (msg) => {
|
|
3499
3040
|
bossStore.appendUpdateNotice(msg);
|
|
3500
3041
|
setUpdatePending(true);
|
|
@@ -3502,8 +3043,8 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3502
3043
|
return () => stopPeriodicUpdateCheck();
|
|
3503
3044
|
}, []);
|
|
3504
3045
|
const workersRunning = state.workers.filter((w) => w.status === "working").length;
|
|
3505
|
-
const titlePrevRef = (0,
|
|
3506
|
-
(0,
|
|
3046
|
+
const titlePrevRef = (0, import_react14.useRef)("");
|
|
3047
|
+
(0, import_react14.useEffect)(() => {
|
|
3507
3048
|
if (!stdout) return;
|
|
3508
3049
|
let title;
|
|
3509
3050
|
if (workersRunning > 0) {
|
|
@@ -3519,13 +3060,13 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3519
3060
|
stdout.write(`\x1B]0;${title}\x1B\\`);
|
|
3520
3061
|
}
|
|
3521
3062
|
}, [stdout, workersRunning, state.phase]);
|
|
3522
|
-
(0,
|
|
3063
|
+
(0, import_react14.useEffect)(() => {
|
|
3523
3064
|
return () => {
|
|
3524
3065
|
stdout?.write(`\x1B]0;GG Boss\x1B\\`);
|
|
3525
3066
|
};
|
|
3526
3067
|
}, [stdout]);
|
|
3527
3068
|
const liveItems = state.liveItems;
|
|
3528
|
-
const terminalHistoryPrinterRef = (0,
|
|
3069
|
+
const terminalHistoryPrinterRef = (0, import_react14.useRef)(
|
|
3529
3070
|
terminalHistoryPrinter ?? createBossTerminalHistoryPrinter({ stream: stdout })
|
|
3530
3071
|
);
|
|
3531
3072
|
const terminalHistoryContext = {
|
|
@@ -3536,21 +3077,21 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3536
3077
|
provider: state.bossProvider,
|
|
3537
3078
|
cwd: process.cwd()
|
|
3538
3079
|
};
|
|
3539
|
-
const printedHistoryIdsRef = (0,
|
|
3540
|
-
(0,
|
|
3080
|
+
const printedHistoryIdsRef = (0, import_react14.useRef)(/* @__PURE__ */ new Set());
|
|
3081
|
+
(0, import_react14.useEffect)(() => {
|
|
3541
3082
|
const printer = terminalHistoryPrinterRef.current;
|
|
3542
3083
|
const pending = state.history.filter((item) => !printedHistoryIdsRef.current.has(item.id));
|
|
3543
3084
|
if (pending.length === 0) return;
|
|
3544
3085
|
printer.print(pending, terminalHistoryContext, { write: writeStdout });
|
|
3545
3086
|
for (const item of pending) printedHistoryIdsRef.current.add(item.id);
|
|
3546
3087
|
}, [columns, state.bossModel, state.bossProvider, state.history, theme, writeStdout]);
|
|
3547
|
-
const overlayResetTimerRef = (0,
|
|
3548
|
-
(0,
|
|
3088
|
+
const overlayResetTimerRef = (0, import_react14.useRef)(null);
|
|
3089
|
+
(0, import_react14.useEffect)(() => {
|
|
3549
3090
|
return () => {
|
|
3550
3091
|
if (overlayResetTimerRef.current) clearTimeout(overlayResetTimerRef.current);
|
|
3551
3092
|
};
|
|
3552
3093
|
}, []);
|
|
3553
|
-
const scheduleOverlayReset = (0,
|
|
3094
|
+
const scheduleOverlayReset = (0, import_react14.useCallback)(() => {
|
|
3554
3095
|
if (!resetUI) return;
|
|
3555
3096
|
if (overlayResetTimerRef.current) clearTimeout(overlayResetTimerRef.current);
|
|
3556
3097
|
overlayResetTimerRef.current = setTimeout(() => {
|
|
@@ -3558,14 +3099,14 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3558
3099
|
resetUI();
|
|
3559
3100
|
}, 0);
|
|
3560
3101
|
}, [resetUI]);
|
|
3561
|
-
const openOverlay = (0,
|
|
3102
|
+
const openOverlay = (0, import_react14.useCallback)(
|
|
3562
3103
|
(next) => {
|
|
3563
3104
|
bossStore.setOverlay(next);
|
|
3564
3105
|
scheduleOverlayReset();
|
|
3565
3106
|
},
|
|
3566
3107
|
[scheduleOverlayReset]
|
|
3567
3108
|
);
|
|
3568
|
-
const closeOverlay = (0,
|
|
3109
|
+
const closeOverlay = (0, import_react14.useCallback)(() => {
|
|
3569
3110
|
bossStore.setOverlay(null);
|
|
3570
3111
|
scheduleOverlayReset();
|
|
3571
3112
|
}, [scheduleOverlayReset]);
|
|
@@ -3574,12 +3115,12 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3574
3115
|
(pending) => bossStore.setExitPending(pending),
|
|
3575
3116
|
() => exit()
|
|
3576
3117
|
);
|
|
3577
|
-
(0,
|
|
3118
|
+
(0, import_react14.useEffect)(() => {
|
|
3578
3119
|
if (state.pendingFlush.length > 0) {
|
|
3579
3120
|
bossStore.commitPendingFlush();
|
|
3580
3121
|
}
|
|
3581
3122
|
}, [state.flushGeneration, state.pendingFlush.length]);
|
|
3582
|
-
const handleAbort = (0,
|
|
3123
|
+
const handleAbort = (0, import_react14.useCallback)(() => {
|
|
3583
3124
|
if (state.phase === "working") {
|
|
3584
3125
|
boss.abort();
|
|
3585
3126
|
return;
|
|
@@ -3674,14 +3215,14 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3674
3215
|
const controlsRows = 7 + (statusSlotVisible ? 1 : 0) + (state.exitPending ? 0 : 1);
|
|
3675
3216
|
const availableLiveRows = Math.max(1, rows - controlsRows);
|
|
3676
3217
|
if (rows < 14) {
|
|
3677
|
-
return /* @__PURE__ */ (0,
|
|
3678
|
-
/* @__PURE__ */ (0,
|
|
3679
|
-
/* @__PURE__ */ (0,
|
|
3218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Box_default, { flexDirection: "column", width: columns, paddingX: 1, marginTop: 1, children: [
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { bold: true, color: COLORS.accent, children: "Terminal too small" }),
|
|
3220
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { color: COLORS.primary, children: `Resize to at least 14 rows to use GG Boss (currently ${rows}).` })
|
|
3680
3221
|
] });
|
|
3681
3222
|
}
|
|
3682
3223
|
const lastPendingHistoryItem = state.pendingFlush[state.pendingFlush.length - 1];
|
|
3683
3224
|
const lastHistoryItem = state.history[state.history.length - 1];
|
|
3684
|
-
const livePane = /* @__PURE__ */ (0,
|
|
3225
|
+
const livePane = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3685
3226
|
BossStreamingTurnView,
|
|
3686
3227
|
{
|
|
3687
3228
|
turn: state.streaming,
|
|
@@ -3692,7 +3233,7 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3692
3233
|
availableTerminalHeight: availableLiveRows
|
|
3693
3234
|
}
|
|
3694
3235
|
);
|
|
3695
|
-
return /* @__PURE__ */ (0,
|
|
3236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3696
3237
|
BossChatScreen,
|
|
3697
3238
|
{
|
|
3698
3239
|
boss,
|
|
@@ -3725,7 +3266,7 @@ function BossAppInner({ boss, resetUI, terminalHistoryPrinter }) {
|
|
|
3725
3266
|
void boss.setBossThinking(next);
|
|
3726
3267
|
},
|
|
3727
3268
|
commands: BOSS_SLASH_COMMANDS,
|
|
3728
|
-
scopeBadge: /* @__PURE__ */ (0,
|
|
3269
|
+
scopeBadge: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ScopePill, { scope: state.scope }),
|
|
3729
3270
|
onCloseOverlay: closeOverlay,
|
|
3730
3271
|
onModelSelect: handleModelSelect,
|
|
3731
3272
|
currentRadio,
|
|
@@ -3762,12 +3303,12 @@ function ScopePill({ scope }) {
|
|
|
3762
3303
|
const isAll = scope === "all";
|
|
3763
3304
|
const bg = isAll ? COLORS.accent : projectColor(scope);
|
|
3764
3305
|
const label = isAll ? "All" : scope;
|
|
3765
|
-
return /* @__PURE__ */ (0,
|
|
3766
|
-
/* @__PURE__ */ (0,
|
|
3767
|
-
/* @__PURE__ */ (0,
|
|
3768
|
-
/* @__PURE__ */ (0,
|
|
3306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Text, { children: [
|
|
3307
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { color: theme.textDim, children: "Project " }),
|
|
3308
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { color: "black", backgroundColor: bg, bold: true, children: ` ${label} ` }),
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Text, { color: theme.textDim, children: [
|
|
3769
3310
|
" ",
|
|
3770
|
-
/* @__PURE__ */ (0,
|
|
3311
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { color: theme.primary, children: "Tab" }),
|
|
3771
3312
|
" to switch"
|
|
3772
3313
|
] })
|
|
3773
3314
|
] });
|
|
@@ -3831,7 +3372,7 @@ function renderBossApp(opts) {
|
|
|
3831
3372
|
process.stdout.write(VIEWPORT_CLEAR);
|
|
3832
3373
|
}
|
|
3833
3374
|
ref.instance = render_default(
|
|
3834
|
-
/* @__PURE__ */ (0,
|
|
3375
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3835
3376
|
BossApp,
|
|
3836
3377
|
{
|
|
3837
3378
|
boss: opts.boss,
|
|
@@ -3843,7 +3384,7 @@ function renderBossApp(opts) {
|
|
|
3843
3384
|
);
|
|
3844
3385
|
};
|
|
3845
3386
|
const instance = render_default(
|
|
3846
|
-
/* @__PURE__ */ (0,
|
|
3387
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BossApp, { boss: opts.boss, resetUI, terminalHistoryPrinter }),
|
|
3847
3388
|
INK_OPTIONS
|
|
3848
3389
|
);
|
|
3849
3390
|
ref.instance = instance;
|
|
@@ -3904,8 +3445,8 @@ function renderBossApp(opts) {
|
|
|
3904
3445
|
|
|
3905
3446
|
// src/splash.tsx
|
|
3906
3447
|
init_esm_shims();
|
|
3907
|
-
var
|
|
3908
|
-
var
|
|
3448
|
+
var import_react15 = __toESM(require_react(), 1);
|
|
3449
|
+
var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
|
|
3909
3450
|
var SPLASH_LINES = [
|
|
3910
3451
|
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ",
|
|
3911
3452
|
" \u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2588\u2588\u2588 \u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2588\u2588\u2588 \u2591\u2591\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2588\u2588\u2588 ",
|
|
@@ -3923,7 +3464,7 @@ function colorForLine(lineIdx, totalLines, offset) {
|
|
|
3923
3464
|
return GRADIENT[idx];
|
|
3924
3465
|
}
|
|
3925
3466
|
function SplashLogo({ offset }) {
|
|
3926
|
-
return /* @__PURE__ */ (0,
|
|
3467
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box_default, { flexDirection: "column", children: SPLASH_LINES.map((line, i) => {
|
|
3927
3468
|
const hue = colorForLine(i, SPLASH_LINES.length, offset);
|
|
3928
3469
|
const segments = [];
|
|
3929
3470
|
let buf = "";
|
|
@@ -3944,12 +3485,12 @@ function SplashLogo({ offset }) {
|
|
|
3944
3485
|
}
|
|
3945
3486
|
}
|
|
3946
3487
|
if (buf) segments.push({ text: buf, dim: bufDim });
|
|
3947
|
-
return /* @__PURE__ */ (0,
|
|
3488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { children: segments.map((seg, j) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: hue, dimColor: seg.dim, children: seg.text }, j)) }, i);
|
|
3948
3489
|
}) });
|
|
3949
3490
|
}
|
|
3950
3491
|
function SplashScreen({ caption }) {
|
|
3951
|
-
const [offset, setOffset] = (0,
|
|
3952
|
-
(0,
|
|
3492
|
+
const [offset, setOffset] = (0, import_react15.useState)(0);
|
|
3493
|
+
(0, import_react15.useEffect)(() => {
|
|
3953
3494
|
const timer = setInterval(() => {
|
|
3954
3495
|
setOffset((o) => o + 1);
|
|
3955
3496
|
}, 120);
|
|
@@ -3957,11 +3498,11 @@ function SplashScreen({ caption }) {
|
|
|
3957
3498
|
clearInterval(timer);
|
|
3958
3499
|
};
|
|
3959
3500
|
}, []);
|
|
3960
|
-
const [size, setSize] = (0,
|
|
3501
|
+
const [size, setSize] = (0, import_react15.useState)(() => ({
|
|
3961
3502
|
columns: process.stdout.columns ?? 80,
|
|
3962
3503
|
rows: process.stdout.rows ?? 24
|
|
3963
3504
|
}));
|
|
3964
|
-
(0,
|
|
3505
|
+
(0, import_react15.useEffect)(() => {
|
|
3965
3506
|
const handler = () => setSize({
|
|
3966
3507
|
columns: process.stdout.columns ?? 80,
|
|
3967
3508
|
rows: process.stdout.rows ?? 24
|
|
@@ -3973,27 +3514,27 @@ function SplashScreen({ caption }) {
|
|
|
3973
3514
|
}, []);
|
|
3974
3515
|
const SPLASH_BLOCK_HEIGHT = SPLASH_LINES.length + 3;
|
|
3975
3516
|
const verticalPad = Math.max(0, Math.floor((size.rows - SPLASH_BLOCK_HEIGHT) / 2));
|
|
3976
|
-
return /* @__PURE__ */ (0,
|
|
3977
|
-
/* @__PURE__ */ (0,
|
|
3978
|
-
/* @__PURE__ */ (0,
|
|
3979
|
-
/* @__PURE__ */ (0,
|
|
3980
|
-
/* @__PURE__ */ (0,
|
|
3981
|
-
/* @__PURE__ */ (0,
|
|
3982
|
-
/* @__PURE__ */ (0,
|
|
3517
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { flexDirection: "column", width: size.columns, height: size.rows, alignItems: "center", children: [
|
|
3518
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box_default, { height: verticalPad, flexShrink: 0 }),
|
|
3519
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { flexDirection: "column", alignItems: "flex-start", flexShrink: 0, children: [
|
|
3520
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SplashLogo, { offset }),
|
|
3521
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box_default, { width: SPLASH_WIDTH, marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Text, { children: [
|
|
3522
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: COLORS.text, bold: true, children: BRAND }),
|
|
3523
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Text, { color: COLORS.textDim, children: [
|
|
3983
3524
|
" v",
|
|
3984
3525
|
VERSION
|
|
3985
3526
|
] }),
|
|
3986
|
-
/* @__PURE__ */ (0,
|
|
3987
|
-
/* @__PURE__ */ (0,
|
|
3527
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: COLORS.textDim, children: " \xB7 By " }),
|
|
3528
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: COLORS.text, bold: true, children: AUTHOR })
|
|
3988
3529
|
] }) }),
|
|
3989
|
-
/* @__PURE__ */ (0,
|
|
3530
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box_default, { width: SPLASH_WIDTH, justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: COLORS.textDim, children: caption ?? "Spinning up the orchestrator\u2026" }) })
|
|
3990
3531
|
] })
|
|
3991
3532
|
] });
|
|
3992
3533
|
}
|
|
3993
3534
|
function showSplash(opts) {
|
|
3994
3535
|
const start = Date.now();
|
|
3995
3536
|
void playSplashAudio();
|
|
3996
|
-
const instance = render_default(/* @__PURE__ */ (0,
|
|
3537
|
+
const instance = render_default(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SplashScreen, { caption: opts.caption }));
|
|
3997
3538
|
const audioDurationMs = getSplashAudioDurationMs();
|
|
3998
3539
|
const defaultMinMs = audioDurationMs + 200;
|
|
3999
3540
|
return {
|
|
@@ -4092,10 +3633,12 @@ async function runServeSubcommand(argv) {
|
|
|
4092
3633
|
process.exit(1);
|
|
4093
3634
|
}
|
|
4094
3635
|
const settings = await loadSettings();
|
|
4095
|
-
const bossProvider =
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
3636
|
+
const { bossProvider, bossModel, workerProvider, workerModel } = await resolveBossAuth({
|
|
3637
|
+
bossProvider: settings.bossProvider ?? "anthropic",
|
|
3638
|
+
bossModel: cliBossModel ?? settings.bossModel ?? "claude-opus-4-8",
|
|
3639
|
+
workerProvider: settings.workerProvider ?? "anthropic",
|
|
3640
|
+
workerModel: cliWorkerModel ?? settings.workerModel ?? "claude-sonnet-4-6"
|
|
3641
|
+
});
|
|
4099
3642
|
await runBossServeMode({
|
|
4100
3643
|
bossProvider,
|
|
4101
3644
|
bossModel,
|
|
@@ -4105,6 +3648,45 @@ async function runServeSubcommand(argv) {
|
|
|
4105
3648
|
telegram: { botToken, userId }
|
|
4106
3649
|
});
|
|
4107
3650
|
}
|
|
3651
|
+
var ALL_PROVIDERS = [
|
|
3652
|
+
"anthropic",
|
|
3653
|
+
"openai",
|
|
3654
|
+
"xiaomi",
|
|
3655
|
+
"gemini",
|
|
3656
|
+
"glm",
|
|
3657
|
+
"moonshot",
|
|
3658
|
+
"minimax",
|
|
3659
|
+
"deepseek",
|
|
3660
|
+
"openrouter"
|
|
3661
|
+
];
|
|
3662
|
+
function bossDefaultModel(provider) {
|
|
3663
|
+
return provider === "anthropic" ? "claude-opus-4-8" : getDefaultModel(provider).id;
|
|
3664
|
+
}
|
|
3665
|
+
async function resolveBossAuth(input) {
|
|
3666
|
+
const auth = new AuthStorage();
|
|
3667
|
+
await auth.load();
|
|
3668
|
+
const stored = await auth.listProviders();
|
|
3669
|
+
const loggedIn = ALL_PROVIDERS.filter((p) => stored.includes(p));
|
|
3670
|
+
if (loggedIn.length === 0) {
|
|
3671
|
+
throw new Error('Not logged in to any provider. Run "ggcoder login" to authenticate.');
|
|
3672
|
+
}
|
|
3673
|
+
const fallback = loggedIn[0];
|
|
3674
|
+
const resolve = (preferredProvider, preferredModel, defaultFor) => {
|
|
3675
|
+
const provider = loggedIn.includes(preferredProvider) ? preferredProvider : fallback;
|
|
3676
|
+
const modelFits = getModel(preferredModel)?.provider === provider;
|
|
3677
|
+
return { provider, model: modelFits ? preferredModel : defaultFor(provider) };
|
|
3678
|
+
};
|
|
3679
|
+
const boss = resolve(input.bossProvider, input.bossModel, bossDefaultModel);
|
|
3680
|
+
const worker = resolve(input.workerProvider, input.workerModel, (p) => getDefaultModel(p).id);
|
|
3681
|
+
const fellBack = boss.provider !== input.bossProvider || worker.provider !== input.workerProvider;
|
|
3682
|
+
return {
|
|
3683
|
+
bossProvider: boss.provider,
|
|
3684
|
+
bossModel: boss.model,
|
|
3685
|
+
workerProvider: worker.provider,
|
|
3686
|
+
workerModel: worker.model,
|
|
3687
|
+
fellBack
|
|
3688
|
+
};
|
|
3689
|
+
}
|
|
4108
3690
|
async function runOrchestrator(args) {
|
|
4109
3691
|
if (args.projects.length === 0) {
|
|
4110
3692
|
const links = await loadLinks();
|
|
@@ -4121,10 +3703,30 @@ async function runOrchestrator(args) {
|
|
|
4121
3703
|
caption: `Spinning up ${args.projects.length} worker${args.projects.length === 1 ? "" : "s"}\u2026`
|
|
4122
3704
|
});
|
|
4123
3705
|
const settings = await loadSettings();
|
|
4124
|
-
const
|
|
4125
|
-
const
|
|
4126
|
-
const
|
|
4127
|
-
const
|
|
3706
|
+
const preferredBossProvider = args.bossProvider ?? settings.bossProvider ?? "anthropic";
|
|
3707
|
+
const preferredBossModel = args.bossModel ?? settings.bossModel ?? "claude-opus-4-8";
|
|
3708
|
+
const preferredWorkerProvider = args.workerProvider ?? settings.workerProvider ?? "anthropic";
|
|
3709
|
+
const preferredWorkerModel = args.workerModel ?? settings.workerModel ?? "claude-sonnet-4-6";
|
|
3710
|
+
const {
|
|
3711
|
+
bossProvider: finalBossProvider,
|
|
3712
|
+
bossModel: finalBossModel,
|
|
3713
|
+
workerProvider: finalWorkerProvider,
|
|
3714
|
+
workerModel: finalWorkerModel,
|
|
3715
|
+
fellBack
|
|
3716
|
+
} = await resolveBossAuth({
|
|
3717
|
+
bossProvider: preferredBossProvider,
|
|
3718
|
+
bossModel: preferredBossModel,
|
|
3719
|
+
workerProvider: preferredWorkerProvider,
|
|
3720
|
+
workerModel: preferredWorkerModel
|
|
3721
|
+
});
|
|
3722
|
+
if (fellBack) {
|
|
3723
|
+
log("INFO", "cli", "provider fallback", {
|
|
3724
|
+
preferredBoss: preferredBossProvider,
|
|
3725
|
+
boss: finalBossProvider,
|
|
3726
|
+
preferredWorker: preferredWorkerProvider,
|
|
3727
|
+
worker: finalWorkerProvider
|
|
3728
|
+
});
|
|
3729
|
+
}
|
|
4128
3730
|
initLogger({
|
|
4129
3731
|
version: VERSION,
|
|
4130
3732
|
bossProvider: finalBossProvider,
|