@bobsworkshop/cli 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -3
- package/dist/bob.js +475 -163
- package/package.json +1 -1
package/dist/bob.js
CHANGED
|
@@ -1502,6 +1502,82 @@ function sleep2(ms) {
|
|
|
1502
1502
|
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
1503
1503
|
}
|
|
1504
1504
|
|
|
1505
|
+
// src/core/reference-resolver.ts
|
|
1506
|
+
var RESERVED_COMMANDS = [
|
|
1507
|
+
"help",
|
|
1508
|
+
"clear",
|
|
1509
|
+
"reset",
|
|
1510
|
+
"surface",
|
|
1511
|
+
"promote",
|
|
1512
|
+
"constraints",
|
|
1513
|
+
"personalized",
|
|
1514
|
+
"exit",
|
|
1515
|
+
"quit",
|
|
1516
|
+
"new",
|
|
1517
|
+
"ref",
|
|
1518
|
+
"pin",
|
|
1519
|
+
"unpin",
|
|
1520
|
+
"sticky"
|
|
1521
|
+
];
|
|
1522
|
+
function detectReference(input) {
|
|
1523
|
+
if (!input.startsWith("/")) return null;
|
|
1524
|
+
const match = input.match(
|
|
1525
|
+
/^\/([a-zA-Z0-9_-]+)(?:\s*-\s*(.+?))?(?:\s|$)/
|
|
1526
|
+
);
|
|
1527
|
+
if (!match) return null;
|
|
1528
|
+
const alias = match[1].toLowerCase().trim();
|
|
1529
|
+
if (RESERVED_COMMANDS.includes(alias)) return null;
|
|
1530
|
+
return {
|
|
1531
|
+
alias,
|
|
1532
|
+
filename: match[2]?.trim()
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
async function fetchAvailableReferences(domain, uid) {
|
|
1536
|
+
try {
|
|
1537
|
+
const result = await callCloudFunction("getAvailableReferences", {
|
|
1538
|
+
domain,
|
|
1539
|
+
uid
|
|
1540
|
+
});
|
|
1541
|
+
return result?.references ?? [];
|
|
1542
|
+
} catch (e) {
|
|
1543
|
+
console.error("[REF] fetchAvailableReferences failed:", e);
|
|
1544
|
+
return [];
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
async function fetchProjectFiles(domain, projectId, query = "") {
|
|
1548
|
+
try {
|
|
1549
|
+
const result = await callCloudFunction("getProjectReferenceFiles", {
|
|
1550
|
+
domain,
|
|
1551
|
+
projectId,
|
|
1552
|
+
query
|
|
1553
|
+
});
|
|
1554
|
+
return result?.files ?? [];
|
|
1555
|
+
} catch (e) {
|
|
1556
|
+
console.error("[REF] fetchProjectFiles failed:", e);
|
|
1557
|
+
return [];
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
async function loadStickyReference(docPath) {
|
|
1561
|
+
try {
|
|
1562
|
+
const result = await callCloudFunction("getStickyReference", { docPath });
|
|
1563
|
+
if (!result?.active || !result?.alias) return null;
|
|
1564
|
+
return { alias: result.alias };
|
|
1565
|
+
} catch (e) {
|
|
1566
|
+
return null;
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
async function saveStickyReference(docPath, alias, active) {
|
|
1570
|
+
try {
|
|
1571
|
+
await callCloudFunction("setStickyReference", {
|
|
1572
|
+
docPath,
|
|
1573
|
+
alias,
|
|
1574
|
+
active
|
|
1575
|
+
});
|
|
1576
|
+
} catch (e) {
|
|
1577
|
+
console.error("[REF] saveStickyReference failed:", e);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1505
1581
|
// src/commands/deepdive.ts
|
|
1506
1582
|
var BRAND_SECONDARY2 = chalk5.hex("#FFAB00");
|
|
1507
1583
|
var SUCCESS2 = chalk5.hex("#66BB6A");
|
|
@@ -1705,6 +1781,10 @@ async function enterDeepDive(config, conversationId, rl) {
|
|
|
1705
1781
|
async function runDeepDiveSession(config, conversationId, parentMessageId, initiatingPrompt, rl) {
|
|
1706
1782
|
const previewText = initiatingPrompt.slice(0, 50) + (initiatingPrompt.length > 50 ? "..." : "");
|
|
1707
1783
|
const isLocalProvider = config.provider === "local" && config.localEndpoint;
|
|
1784
|
+
const domain = config.email?.split("@").pop()?.toLowerCase() ?? "";
|
|
1785
|
+
const uid = config.uid ?? "";
|
|
1786
|
+
const threadDocPath = `Organizations/${domain}/OrgUsers/${uid}/BobGlobalChat/${conversationId}/Messages/${parentMessageId}/sandbox/thread`;
|
|
1787
|
+
let stickyRef = await loadStickyReference(threadDocPath);
|
|
1708
1788
|
console.log("");
|
|
1709
1789
|
console.log(MODE_DEEPDIVE2(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
1710
1790
|
console.log(MODE_DEEPDIVE2(" \u2551") + chalk5.bold(MODE_DEEPDIVE2(" \u{1F93F} DEEP DIVE ")) + MODE_DEEPDIVE2("\u2551"));
|
|
@@ -1712,15 +1792,20 @@ async function runDeepDiveSession(config, conversationId, parentMessageId, initi
|
|
|
1712
1792
|
if (isLocalProvider) {
|
|
1713
1793
|
console.log(MODE_DEEPDIVE2(" \u2551") + MUTED2(" Provider: Local model (sovereign handoff)"));
|
|
1714
1794
|
}
|
|
1795
|
+
if (stickyRef) {
|
|
1796
|
+
console.log(MODE_DEEPDIVE2(" \u2551") + AMBER(` \u{1F4CC} Sticky ref: /${stickyRef.alias}`));
|
|
1797
|
+
}
|
|
1715
1798
|
console.log(MODE_DEEPDIVE2(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
1716
|
-
console.log(MODE_DEEPDIVE2(" \u2551") + MUTED2("
|
|
1799
|
+
console.log(MODE_DEEPDIVE2(" \u2551") + MUTED2(" /surface /promote /clear /constraints ") + MODE_DEEPDIVE2("\u2551"));
|
|
1800
|
+
console.log(MODE_DEEPDIVE2(" \u2551") + MUTED2(" /ref /pin \u2014 manage reference projects ") + MODE_DEEPDIVE2("\u2551"));
|
|
1717
1801
|
console.log(MODE_DEEPDIVE2(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
1718
1802
|
console.log("");
|
|
1719
1803
|
let lastBobResponse = "";
|
|
1720
1804
|
let lastConstraints3 = [];
|
|
1721
1805
|
return new Promise((resolve4) => {
|
|
1722
1806
|
const deepDivePrompt = () => {
|
|
1723
|
-
|
|
1807
|
+
const promptText = stickyRef ? MODE_DEEPDIVE2(` \u{1F4CC} /${stickyRef.alias} \u{1F93F} \u203A `) : MODE_DEEPDIVE2(" \u{1F93F} You: ");
|
|
1808
|
+
rl.question(promptText, async (input) => {
|
|
1724
1809
|
const trimmed = input.trim();
|
|
1725
1810
|
if (!trimmed) {
|
|
1726
1811
|
deepDivePrompt();
|
|
@@ -1795,6 +1880,30 @@ async function runDeepDiveSession(config, conversationId, parentMessageId, initi
|
|
|
1795
1880
|
deepDivePrompt();
|
|
1796
1881
|
return;
|
|
1797
1882
|
}
|
|
1883
|
+
if (trimmed === "/ref") {
|
|
1884
|
+
stickyRef = await handleDeepDiveRefBrowser(domain, uid, threadDocPath, rl);
|
|
1885
|
+
deepDivePrompt();
|
|
1886
|
+
return;
|
|
1887
|
+
}
|
|
1888
|
+
if (trimmed === "/pin") {
|
|
1889
|
+
if (stickyRef) {
|
|
1890
|
+
await saveStickyReference(threadDocPath, null, false);
|
|
1891
|
+
stickyRef = null;
|
|
1892
|
+
console.log("");
|
|
1893
|
+
console.log(MUTED2(" \u{1F4CC} Sticky reference cleared."));
|
|
1894
|
+
console.log("");
|
|
1895
|
+
} else {
|
|
1896
|
+
stickyRef = await handleDeepDiveRefBrowser(domain, uid, threadDocPath, rl);
|
|
1897
|
+
}
|
|
1898
|
+
deepDivePrompt();
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1901
|
+
const inlineRef = detectReference(trimmed);
|
|
1902
|
+
const activeRef = inlineRef ?? stickyRef ?? null;
|
|
1903
|
+
if (activeRef) {
|
|
1904
|
+
console.log("");
|
|
1905
|
+
console.log(AMBER(` \u{1F4CE} Referencing /${activeRef.alias}${activeRef.filename ? ` \u2014 ${activeRef.filename}` : ""}...`));
|
|
1906
|
+
}
|
|
1798
1907
|
renderUserMessage(trimmed);
|
|
1799
1908
|
startElapsedTimer();
|
|
1800
1909
|
try {
|
|
@@ -1821,7 +1930,10 @@ Current request: ${trimmed}` : trimmed;
|
|
|
1821
1930
|
isLocalModel: true,
|
|
1822
1931
|
activePersonaId: null,
|
|
1823
1932
|
localContext,
|
|
1824
|
-
cliMode: true
|
|
1933
|
+
cliMode: true,
|
|
1934
|
+
// ─── REFERENCE PARAMS ───
|
|
1935
|
+
...activeRef && { referenceAlias: activeRef.alias },
|
|
1936
|
+
...activeRef?.filename && { referenceFilename: activeRef.filename }
|
|
1825
1937
|
});
|
|
1826
1938
|
if (!handoffResult?.isHandoff || !handoffResult?.masterPrompt) {
|
|
1827
1939
|
throw new Error("Handoff failed \u2014 no master prompt returned.");
|
|
@@ -1830,7 +1942,18 @@ Current request: ${trimmed}` : trimmed;
|
|
|
1830
1942
|
responseText = await callLocalModel(config.localEndpoint, localMessages);
|
|
1831
1943
|
await callCloudFunction("saveCLIDeepDiveMessage", { conversationId, parentMessageId, message: responseText, sender: "bob", origin: "local-sovereign" });
|
|
1832
1944
|
} else {
|
|
1833
|
-
await callCloudFunction("generateDeepDiveResponse", {
|
|
1945
|
+
await callCloudFunction("generateDeepDiveResponse", {
|
|
1946
|
+
conversationId,
|
|
1947
|
+
parentMessageId,
|
|
1948
|
+
userMessage: trimmed,
|
|
1949
|
+
isLocalModel: false,
|
|
1950
|
+
activePersonaId: null,
|
|
1951
|
+
localContext,
|
|
1952
|
+
cliMode: true,
|
|
1953
|
+
// ─── REFERENCE PARAMS ───
|
|
1954
|
+
...activeRef && { referenceAlias: activeRef.alias },
|
|
1955
|
+
...activeRef?.filename && { referenceFilename: activeRef.filename }
|
|
1956
|
+
});
|
|
1834
1957
|
const latestResult = await callCloudFunction("listCLIDeepDives", { conversationId, action: "getLatestSandboxMessage", parentMessageId });
|
|
1835
1958
|
responseText = latestResult?.message || "Deep dive response saved.";
|
|
1836
1959
|
}
|
|
@@ -1865,6 +1988,77 @@ Current request: ${trimmed}` : trimmed;
|
|
|
1865
1988
|
deepDivePrompt();
|
|
1866
1989
|
});
|
|
1867
1990
|
}
|
|
1991
|
+
async function handleDeepDiveRefBrowser(domain, uid, threadDocPath, rl) {
|
|
1992
|
+
const refs = await fetchAvailableReferences(domain, uid);
|
|
1993
|
+
if (refs.length === 0) {
|
|
1994
|
+
console.log("");
|
|
1995
|
+
console.log(MUTED2(" No shared references available for your account."));
|
|
1996
|
+
console.log("");
|
|
1997
|
+
return null;
|
|
1998
|
+
}
|
|
1999
|
+
console.log("");
|
|
2000
|
+
console.log(AMBER(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
2001
|
+
console.log(AMBER(" \u2551") + chalk5.bold(" \u{1F4CE} AVAILABLE REFERENCES ") + AMBER("\u2551"));
|
|
2002
|
+
console.log(AMBER(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
2003
|
+
refs.forEach((ref, i) => {
|
|
2004
|
+
const line = ` ${String(i + 1).padStart(2)}. /${ref.alias.padEnd(18)} ${MUTED2(ref.repoDisplayName)}`;
|
|
2005
|
+
console.log(AMBER(" \u2551") + line);
|
|
2006
|
+
});
|
|
2007
|
+
console.log(AMBER(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
2008
|
+
console.log(AMBER(" \u2551") + MUTED2(" Enter number to select, 0 to cancel ") + AMBER("\u2551"));
|
|
2009
|
+
console.log(AMBER(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
2010
|
+
console.log("");
|
|
2011
|
+
const answer = await new Promise((resolve4) => {
|
|
2012
|
+
rl.question(AMBER(" Select reference: "), resolve4);
|
|
2013
|
+
});
|
|
2014
|
+
const num = parseInt(answer.trim());
|
|
2015
|
+
if (isNaN(num) || num === 0 || num < 1 || num > refs.length) {
|
|
2016
|
+
console.log(MUTED2(" Cancelled."));
|
|
2017
|
+
console.log("");
|
|
2018
|
+
return null;
|
|
2019
|
+
}
|
|
2020
|
+
const selected = refs[num - 1];
|
|
2021
|
+
const modeAnswer = await new Promise((resolve4) => {
|
|
2022
|
+
rl.question(AMBER(` /${selected.alias} \u2014 whole project (p) or specific file (f)? `), resolve4);
|
|
2023
|
+
});
|
|
2024
|
+
if (modeAnswer.trim().toLowerCase() === "f") {
|
|
2025
|
+
const filterAnswer = await new Promise((resolve4) => {
|
|
2026
|
+
rl.question(AMBER(" Filter files (or Enter for all): "), resolve4);
|
|
2027
|
+
});
|
|
2028
|
+
const files = await fetchProjectFiles(domain, selected.projectId, filterAnswer.trim());
|
|
2029
|
+
if (files.length === 0) {
|
|
2030
|
+
console.log(MUTED2(" No files found. Referencing whole project."));
|
|
2031
|
+
console.log("");
|
|
2032
|
+
return { alias: selected.alias };
|
|
2033
|
+
}
|
|
2034
|
+
console.log("");
|
|
2035
|
+
files.slice(0, 20).forEach((fp, i) => {
|
|
2036
|
+
console.log(MUTED2(` ${String(i + 1).padStart(2)}. ${fp}`));
|
|
2037
|
+
});
|
|
2038
|
+
console.log("");
|
|
2039
|
+
const fileAnswer = await new Promise((resolve4) => {
|
|
2040
|
+
rl.question(AMBER(" Select file (or Enter for whole project): "), resolve4);
|
|
2041
|
+
});
|
|
2042
|
+
const fileNum = parseInt(fileAnswer.trim());
|
|
2043
|
+
if (isNaN(fileNum) || fileNum < 1 || fileNum > files.length) {
|
|
2044
|
+
await saveStickyReference(threadDocPath, selected.alias, true);
|
|
2045
|
+
console.log("");
|
|
2046
|
+
console.log(AMBER(` \u{1F4CC} Sticky reference set: /${selected.alias}`));
|
|
2047
|
+
console.log("");
|
|
2048
|
+
return { alias: selected.alias };
|
|
2049
|
+
}
|
|
2050
|
+
const filename = files[fileNum - 1];
|
|
2051
|
+
console.log("");
|
|
2052
|
+
console.log(AMBER(` \u{1F4CE} File reference: /${selected.alias} \u2014 ${filename}`));
|
|
2053
|
+
console.log("");
|
|
2054
|
+
return { alias: selected.alias, filename };
|
|
2055
|
+
}
|
|
2056
|
+
await saveStickyReference(threadDocPath, selected.alias, true);
|
|
2057
|
+
console.log("");
|
|
2058
|
+
console.log(AMBER(` \u{1F4CC} Sticky reference set: /${selected.alias}`));
|
|
2059
|
+
console.log("");
|
|
2060
|
+
return { alias: selected.alias };
|
|
2061
|
+
}
|
|
1868
2062
|
|
|
1869
2063
|
// src/ui/session-header.ts
|
|
1870
2064
|
import chalk6 from "chalk";
|
|
@@ -2063,6 +2257,7 @@ var WARNING5 = chalk9.hex("#FFC107");
|
|
|
2063
2257
|
var ERROR4 = chalk9.hex("#EF5350");
|
|
2064
2258
|
var MUTED6 = chalk9.hex("#78909C");
|
|
2065
2259
|
var MODE_CHAT3 = chalk9.hex("#26C6DA");
|
|
2260
|
+
var AMBER2 = chalk9.hex("#FFAB00");
|
|
2066
2261
|
var lastConstraints = [];
|
|
2067
2262
|
function registerChatCommand(program2) {
|
|
2068
2263
|
program2.command("chat [message]").description("Chat with Bob \u2014 code-friendly engineering partner").option("-f, --file <path>", "Include a specific file as context").option("--no-context", "Skip local directory context").option("--personalized", "Use personalization mode (Tier 3 only)").option("--new", "Start a fresh conversation").option("-i, --interactive", "Enter interactive conversation mode").action(async (message, options) => {
|
|
@@ -2100,7 +2295,7 @@ ${fileContent}
|
|
|
2100
2295
|
await sendMessage(message, config, conversationId, localContext, options.personalized || false, "standard", [], void 0);
|
|
2101
2296
|
});
|
|
2102
2297
|
}
|
|
2103
|
-
async function sendMessage(message, config, conversationId, localContext, personalized, mode, history, existingRl) {
|
|
2298
|
+
async function sendMessage(message, config, conversationId, localContext, personalized, mode, history, existingRl, activeRef) {
|
|
2104
2299
|
const providerReady = await ensureProvider();
|
|
2105
2300
|
if (!providerReady) return "";
|
|
2106
2301
|
config = getConfig();
|
|
@@ -2166,7 +2361,10 @@ ${fullContext}` : "") },
|
|
|
2166
2361
|
userMessage: message,
|
|
2167
2362
|
additionalContext: { localContext: fullContext || null },
|
|
2168
2363
|
isLocalModel: false,
|
|
2169
|
-
activePersonaId: null
|
|
2364
|
+
activePersonaId: null,
|
|
2365
|
+
// ─── REFERENCE PARAMS ───
|
|
2366
|
+
...activeRef && { referenceAlias: activeRef.alias },
|
|
2367
|
+
...activeRef?.filename && { referenceFilename: activeRef.filename }
|
|
2170
2368
|
});
|
|
2171
2369
|
response = result?.response || result?.data?.response || result?.text || result?.message || "No response received.";
|
|
2172
2370
|
hasProjectContext = result?.hasProjectContext ?? null;
|
|
@@ -2179,7 +2377,21 @@ ${fullContext}` : "") },
|
|
|
2179
2377
|
console.log(MUTED6(" Run `bob login` to authenticate, or set provider to local."));
|
|
2180
2378
|
return "";
|
|
2181
2379
|
}
|
|
2182
|
-
const result = await callCloudFunction("chatWithBobStream", {
|
|
2380
|
+
const result = await callCloudFunction("chatWithBobStream", {
|
|
2381
|
+
userEmail: config.email,
|
|
2382
|
+
userId: config.uid,
|
|
2383
|
+
conversationId,
|
|
2384
|
+
userMessage: message,
|
|
2385
|
+
useContext: true,
|
|
2386
|
+
consultantModelId: "gemini-2.5-flash",
|
|
2387
|
+
useOrgContext: false,
|
|
2388
|
+
isPassalongActive: false,
|
|
2389
|
+
linkedConvoId: null,
|
|
2390
|
+
localContext: fullContext || null,
|
|
2391
|
+
// ─── REFERENCE PARAMS ───
|
|
2392
|
+
...activeRef && { referenceAlias: activeRef.alias },
|
|
2393
|
+
...activeRef?.filename && { referenceFilename: activeRef.filename }
|
|
2394
|
+
});
|
|
2183
2395
|
response = result?.text || result?.response || result?.message || "No response received.";
|
|
2184
2396
|
hasProjectContext = result?.hasProjectContext ?? null;
|
|
2185
2397
|
constraints = result?.constraints || [];
|
|
@@ -2220,15 +2432,22 @@ async function runInteractiveSession(config, conversationId, localContext, perso
|
|
|
2220
2432
|
renderSessionHeader("chat");
|
|
2221
2433
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
2222
2434
|
const history = [];
|
|
2435
|
+
const domain = config.email?.split("@").pop()?.toLowerCase() ?? "";
|
|
2436
|
+
const uid = config.uid ?? "";
|
|
2437
|
+
const convoDocPath = `Organizations/${domain}/OrgUsers/${uid}/BobGlobalChat/${conversationId}`;
|
|
2438
|
+
let stickyRef = await loadStickyReference(convoDocPath);
|
|
2223
2439
|
if (initialMessage) {
|
|
2224
|
-
const
|
|
2440
|
+
const inlineRef = detectReference(initialMessage);
|
|
2441
|
+
const activeRef = inlineRef ?? stickyRef ?? null;
|
|
2442
|
+
const response = await sendMessage(initialMessage, config, conversationId, localContext, personalized, mode, history, rl, activeRef);
|
|
2225
2443
|
if (response) {
|
|
2226
2444
|
history.push({ role: "user", content: initialMessage });
|
|
2227
2445
|
history.push({ role: "assistant", content: response });
|
|
2228
2446
|
}
|
|
2229
2447
|
}
|
|
2230
2448
|
const prompt = () => {
|
|
2231
|
-
|
|
2449
|
+
const promptText = stickyRef ? AMBER2(` \u{1F4CC} /${stickyRef.alias} \u203A `) : SUCCESS6(" You: ");
|
|
2450
|
+
rl.question(promptText, async (input) => {
|
|
2232
2451
|
const trimmed = input.trim();
|
|
2233
2452
|
if (!trimmed) {
|
|
2234
2453
|
prompt();
|
|
@@ -2267,6 +2486,24 @@ async function runInteractiveSession(config, conversationId, localContext, perso
|
|
|
2267
2486
|
prompt();
|
|
2268
2487
|
return;
|
|
2269
2488
|
}
|
|
2489
|
+
if (trimmed === "/ref") {
|
|
2490
|
+
stickyRef = await handleRefBrowser(domain, uid, convoDocPath, rl);
|
|
2491
|
+
prompt();
|
|
2492
|
+
return;
|
|
2493
|
+
}
|
|
2494
|
+
if (trimmed === "/pin") {
|
|
2495
|
+
if (stickyRef) {
|
|
2496
|
+
await saveStickyReference(convoDocPath, null, false);
|
|
2497
|
+
stickyRef = null;
|
|
2498
|
+
console.log("");
|
|
2499
|
+
console.log(MUTED6(" \u{1F4CC} Sticky reference cleared."));
|
|
2500
|
+
console.log("");
|
|
2501
|
+
} else {
|
|
2502
|
+
stickyRef = await handleRefBrowser(domain, uid, convoDocPath, rl);
|
|
2503
|
+
}
|
|
2504
|
+
prompt();
|
|
2505
|
+
return;
|
|
2506
|
+
}
|
|
2270
2507
|
if (trimmed.startsWith("/include ")) {
|
|
2271
2508
|
const filePath = trimmed.slice(9).trim();
|
|
2272
2509
|
const content = readFileContent(filePath);
|
|
@@ -2337,7 +2574,13 @@ ${content}
|
|
|
2337
2574
|
prompt();
|
|
2338
2575
|
return;
|
|
2339
2576
|
}
|
|
2340
|
-
const
|
|
2577
|
+
const inlineRef = detectReference(trimmed);
|
|
2578
|
+
const activeRef = inlineRef ?? stickyRef ?? null;
|
|
2579
|
+
if (activeRef) {
|
|
2580
|
+
console.log("");
|
|
2581
|
+
console.log(AMBER2(` \u{1F4CE} Referencing /${activeRef.alias}${activeRef.filename ? ` \u2014 ${activeRef.filename}` : ""}...`));
|
|
2582
|
+
}
|
|
2583
|
+
const response = await sendMessage(trimmed, config, conversationId, localContext, personalized, mode, history, rl, activeRef);
|
|
2341
2584
|
if (response) {
|
|
2342
2585
|
history.push({ role: "user", content: trimmed });
|
|
2343
2586
|
history.push({ role: "assistant", content: response });
|
|
@@ -2347,6 +2590,81 @@ ${content}
|
|
|
2347
2590
|
};
|
|
2348
2591
|
prompt();
|
|
2349
2592
|
}
|
|
2593
|
+
async function handleRefBrowser(domain, uid, docPath, rl) {
|
|
2594
|
+
const refs = await fetchAvailableReferences(domain, uid);
|
|
2595
|
+
if (refs.length === 0) {
|
|
2596
|
+
console.log("");
|
|
2597
|
+
console.log(MUTED6(" No shared references available for your account."));
|
|
2598
|
+
console.log("");
|
|
2599
|
+
return null;
|
|
2600
|
+
}
|
|
2601
|
+
console.log("");
|
|
2602
|
+
console.log(AMBER2(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
2603
|
+
console.log(AMBER2(" \u2551") + chalk9.bold(" \u{1F4CE} AVAILABLE REFERENCES ") + AMBER2("\u2551"));
|
|
2604
|
+
console.log(AMBER2(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
2605
|
+
refs.forEach((ref, i) => {
|
|
2606
|
+
const line = ` ${String(i + 1).padStart(2)}. /${ref.alias.padEnd(18)} ${MUTED6(ref.repoDisplayName)}`;
|
|
2607
|
+
console.log(AMBER2(" \u2551") + line);
|
|
2608
|
+
});
|
|
2609
|
+
console.log(AMBER2(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
2610
|
+
console.log(AMBER2(" \u2551") + MUTED6(" Enter number to select, 0 to cancel ") + AMBER2("\u2551"));
|
|
2611
|
+
console.log(AMBER2(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
2612
|
+
console.log("");
|
|
2613
|
+
const answer = await new Promise((resolve4) => {
|
|
2614
|
+
rl.question(AMBER2(" Select reference: "), resolve4);
|
|
2615
|
+
});
|
|
2616
|
+
const num = parseInt(answer.trim());
|
|
2617
|
+
if (isNaN(num) || num === 0 || num < 1 || num > refs.length) {
|
|
2618
|
+
console.log(MUTED6(" Cancelled."));
|
|
2619
|
+
console.log("");
|
|
2620
|
+
return null;
|
|
2621
|
+
}
|
|
2622
|
+
const selected = refs[num - 1];
|
|
2623
|
+
const modeAnswer = await new Promise((resolve4) => {
|
|
2624
|
+
rl.question(AMBER2(` /${selected.alias} \u2014 whole project (p) or specific file (f)? `), resolve4);
|
|
2625
|
+
});
|
|
2626
|
+
if (modeAnswer.trim().toLowerCase() === "f") {
|
|
2627
|
+
return await handleFileBrowser(domain, selected, rl, docPath);
|
|
2628
|
+
}
|
|
2629
|
+
await saveStickyReference(docPath, selected.alias, true);
|
|
2630
|
+
console.log("");
|
|
2631
|
+
console.log(AMBER2(` \u{1F4CC} Sticky reference set: /${selected.alias}`));
|
|
2632
|
+
console.log("");
|
|
2633
|
+
return { alias: selected.alias };
|
|
2634
|
+
}
|
|
2635
|
+
async function handleFileBrowser(domain, project, rl, docPath) {
|
|
2636
|
+
const filterAnswer = await new Promise((resolve4) => {
|
|
2637
|
+
rl.question(AMBER2(" Filter files (or Enter for all): "), resolve4);
|
|
2638
|
+
});
|
|
2639
|
+
const files = await fetchProjectFiles(domain, project.projectId, filterAnswer.trim());
|
|
2640
|
+
if (files.length === 0) {
|
|
2641
|
+
console.log(MUTED6(" No files found. Referencing whole project."));
|
|
2642
|
+
console.log("");
|
|
2643
|
+
return { alias: project.alias };
|
|
2644
|
+
}
|
|
2645
|
+
console.log("");
|
|
2646
|
+
console.log(AMBER2(` \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557`));
|
|
2647
|
+
console.log(AMBER2(` \u2551`) + chalk9.bold(` \u{1F4C4} /${project.alias} \u2014 Files `) + AMBER2(`\u2551`));
|
|
2648
|
+
console.log(AMBER2(` \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`));
|
|
2649
|
+
files.slice(0, 20).forEach((fp, i) => {
|
|
2650
|
+
const line = ` ${String(i + 1).padStart(2)}. ${fp}`;
|
|
2651
|
+
console.log(AMBER2(" \u2551") + MUTED6(line.slice(0, 42).padEnd(42)) + AMBER2("\u2551"));
|
|
2652
|
+
});
|
|
2653
|
+
console.log(AMBER2(` \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`));
|
|
2654
|
+
console.log("");
|
|
2655
|
+
const fileAnswer = await new Promise((resolve4) => {
|
|
2656
|
+
rl.question(AMBER2(" Select file (or Enter for whole project): "), resolve4);
|
|
2657
|
+
});
|
|
2658
|
+
const fileNum = parseInt(fileAnswer.trim());
|
|
2659
|
+
if (isNaN(fileNum) || fileNum < 1 || fileNum > files.length) {
|
|
2660
|
+
return { alias: project.alias };
|
|
2661
|
+
}
|
|
2662
|
+
const filename = files[fileNum - 1];
|
|
2663
|
+
console.log("");
|
|
2664
|
+
console.log(AMBER2(` \u{1F4CE} File reference: /${project.alias} \u2014 ${filename}`));
|
|
2665
|
+
console.log("");
|
|
2666
|
+
return { alias: project.alias, filename };
|
|
2667
|
+
}
|
|
2350
2668
|
|
|
2351
2669
|
// src/commands/consult.ts
|
|
2352
2670
|
import chalk10 from "chalk";
|
|
@@ -3856,7 +4174,7 @@ import * as fs8 from "fs";
|
|
|
3856
4174
|
import * as path9 from "path";
|
|
3857
4175
|
var RED = chalk18.hex("#EF5350");
|
|
3858
4176
|
var GREEN = chalk18.hex("#66BB6A");
|
|
3859
|
-
var
|
|
4177
|
+
var AMBER3 = chalk18.hex("#FFAB00");
|
|
3860
4178
|
var BLUE = chalk18.hex("#42A5F5");
|
|
3861
4179
|
var GRAY = chalk18.gray;
|
|
3862
4180
|
var BORDER4 = chalk18.hex("#455A64");
|
|
@@ -3950,7 +4268,7 @@ async function runTier3Autonomy(config, conversationId) {
|
|
|
3950
4268
|
if (text.includes("[ACTION:GITHUB_PUSH_REQUEST:")) {
|
|
3951
4269
|
console.log("");
|
|
3952
4270
|
console.log(GREEN(" \u2705 All tasks complete!"));
|
|
3953
|
-
console.log(
|
|
4271
|
+
console.log(AMBER3(" \u{1F4E4} MiniBob wants to push to GitHub."));
|
|
3954
4272
|
const rl = readline6.createInterface({ input: process.stdin, output: process.stdout });
|
|
3955
4273
|
const answer = await new Promise((resolve4) => {
|
|
3956
4274
|
rl.question(CYAN(" Approve push? (y/n): "), resolve4);
|
|
@@ -3988,7 +4306,7 @@ async function runTier3Autonomy(config, conversationId) {
|
|
|
3988
4306
|
}
|
|
3989
4307
|
console.log("");
|
|
3990
4308
|
console.log(BORDER4(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
3991
|
-
console.log(BORDER4(" \u2551") +
|
|
4309
|
+
console.log(BORDER4(" \u2551") + AMBER3(" \u25C6 AUTONOMY SESSION COMPLETE"));
|
|
3992
4310
|
console.log(BORDER4(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
3993
4311
|
console.log(BORDER4(" \u2551") + GREEN(` \u2705 Tasks completed: ${tasksDone}/${totalTasks}`));
|
|
3994
4312
|
console.log(BORDER4(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
@@ -4062,7 +4380,7 @@ async function runTier1Autonomy(config, options) {
|
|
|
4062
4380
|
console.log("");
|
|
4063
4381
|
console.log("");
|
|
4064
4382
|
console.log(BORDER4(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
4065
|
-
console.log(BORDER4(" \u2551") +
|
|
4383
|
+
console.log(BORDER4(" \u2551") + AMBER3(" \u25C6 MINIBOB AUTONOMY REPORT"));
|
|
4066
4384
|
console.log(BORDER4(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
4067
4385
|
console.log(BORDER4(" \u2551") + GREEN(` \u2705 Fixed: ${fixed} files`));
|
|
4068
4386
|
if (failed > 0) {
|
|
@@ -4123,7 +4441,7 @@ async function showAutonomyStatus(config, conversationId) {
|
|
|
4123
4441
|
spinner.stop();
|
|
4124
4442
|
if (result?.lines && result.lines.length > 0) {
|
|
4125
4443
|
console.log("");
|
|
4126
|
-
console.log(
|
|
4444
|
+
console.log(AMBER3(" \u25C6 Recent Autonomy Activity:"));
|
|
4127
4445
|
console.log(GRAY(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
4128
4446
|
for (const line of result.lines) {
|
|
4129
4447
|
console.log(GRAY(` ${line.text}`));
|
|
@@ -4241,7 +4559,7 @@ var lastLocalTodoLines = 0;
|
|
|
4241
4559
|
function renderLocalTodoList(queue) {
|
|
4242
4560
|
const lines = [];
|
|
4243
4561
|
lines.push("");
|
|
4244
|
-
lines.push(
|
|
4562
|
+
lines.push(AMBER3(" \u{1F4CB} MiniBob Autonomy Queue"));
|
|
4245
4563
|
lines.push(GRAY(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
4246
4564
|
for (let i = 0; i < queue.length; i++) {
|
|
4247
4565
|
const task = queue[i];
|
|
@@ -4255,7 +4573,7 @@ function renderLocalTodoList(queue) {
|
|
|
4255
4573
|
break;
|
|
4256
4574
|
case "working":
|
|
4257
4575
|
icon = "\u23F3";
|
|
4258
|
-
color =
|
|
4576
|
+
color = AMBER3;
|
|
4259
4577
|
break;
|
|
4260
4578
|
case "failed":
|
|
4261
4579
|
icon = "\u2717";
|
|
@@ -4306,7 +4624,7 @@ import * as path10 from "path";
|
|
|
4306
4624
|
import * as crypto2 from "crypto";
|
|
4307
4625
|
import axios from "axios";
|
|
4308
4626
|
var GREEN2 = chalk19.hex("#66BB6A");
|
|
4309
|
-
var
|
|
4627
|
+
var AMBER4 = chalk19.hex("#FFAB00");
|
|
4310
4628
|
var RED2 = chalk19.hex("#EF5350");
|
|
4311
4629
|
var GRAY2 = chalk19.gray;
|
|
4312
4630
|
var CYAN2 = chalk19.cyan;
|
|
@@ -4403,7 +4721,8 @@ function registerServeCommand(program2) {
|
|
|
4403
4721
|
console.log("");
|
|
4404
4722
|
return;
|
|
4405
4723
|
}
|
|
4406
|
-
|
|
4724
|
+
const conversationId = getActiveConversationId(process.cwd()) || config.conversationId;
|
|
4725
|
+
if (!conversationId) {
|
|
4407
4726
|
console.log("");
|
|
4408
4727
|
console.log(RED2(" \u274C No active conversation."));
|
|
4409
4728
|
console.log(GRAY2(" Active Bob must be bound to a conversation."));
|
|
@@ -4436,11 +4755,11 @@ function registerServeCommand(program2) {
|
|
|
4436
4755
|
console.log(GRAY2(` Your current tier: ${userTier}`));
|
|
4437
4756
|
console.log("");
|
|
4438
4757
|
if (isOrgUser) {
|
|
4439
|
-
console.log(
|
|
4758
|
+
console.log(AMBER4(" \u{1F3E2} Contact your organization administrator to upgrade your tier."));
|
|
4440
4759
|
console.log(GRAY2(` Organization: ${domain}`));
|
|
4441
4760
|
console.log(GRAY2(" Admin Dashboard: https://bobs-workshop.web.app/#/bobsadmindashboard"));
|
|
4442
4761
|
} else {
|
|
4443
|
-
console.log(
|
|
4762
|
+
console.log(AMBER4(" \u{1F680} Upgrade to unlock remote execution:"));
|
|
4444
4763
|
console.log("");
|
|
4445
4764
|
console.log(GRAY2(" Starter \u2014 15s polling, 15 min idle timeout"));
|
|
4446
4765
|
console.log(GRAY2(" Pro \u2014 10s polling, sleep mode, 1 hour idle timeout"));
|
|
@@ -4455,10 +4774,10 @@ function registerServeCommand(program2) {
|
|
|
4455
4774
|
const machineId = os2.hostname();
|
|
4456
4775
|
const projectName = path10.basename(process.cwd());
|
|
4457
4776
|
const sessionId = `${machineId}_${Date.now()}`;
|
|
4458
|
-
await startActiveBob(config, sessionId, machineId, projectName, tierConfig, userTier);
|
|
4777
|
+
await startActiveBob(config, conversationId, sessionId, machineId, projectName, tierConfig, userTier);
|
|
4459
4778
|
});
|
|
4460
4779
|
}
|
|
4461
|
-
async function startActiveBob(config, sessionId, machineId, projectName, tierConfig, userTier) {
|
|
4780
|
+
async function startActiveBob(config, conversationId, sessionId, machineId, projectName, tierConfig, userTier) {
|
|
4462
4781
|
console.log("");
|
|
4463
4782
|
console.log(BORDER5(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
4464
4783
|
console.log(BORDER5(" \u2551") + CYAN2(" \u{1F310} Bob Serve \u2014 Active Bob Online ") + BORDER5("\u2551"));
|
|
@@ -4467,8 +4786,8 @@ async function startActiveBob(config, sessionId, machineId, projectName, tierCon
|
|
|
4467
4786
|
console.log(BORDER5(" \u2551") + GRAY2(` Machine: ${machineId}`));
|
|
4468
4787
|
console.log(BORDER5(" \u2551") + GRAY2(` Project: ${projectName} (${process.cwd()})`));
|
|
4469
4788
|
console.log(BORDER5(" \u2551") + GRAY2(` Session: ${sessionId.slice(0, 30)}...`));
|
|
4470
|
-
console.log(BORDER5(" \u2551") + GRAY2(` Convo: ${
|
|
4471
|
-
console.log(BORDER5(" \u2551") +
|
|
4789
|
+
console.log(BORDER5(" \u2551") + GRAY2(` Convo: ${conversationId?.slice(0, 24)}...`));
|
|
4790
|
+
console.log(BORDER5(" \u2551") + AMBER4(` Tier: ${userTier}`));
|
|
4472
4791
|
console.log(BORDER5(" \u2551") + GRAY2(` Polling: every ${tierConfig.activeInterval / 1e3}s`));
|
|
4473
4792
|
if (tierConfig.sleepInterval) {
|
|
4474
4793
|
console.log(BORDER5(" \u2551") + GRAY2(` Sleep: every ${tierConfig.sleepInterval / 1e3}s after ${tierConfig.idleThreshold / 6e4} min idle`));
|
|
@@ -4487,7 +4806,7 @@ async function startActiveBob(config, sessionId, machineId, projectName, tierCon
|
|
|
4487
4806
|
console.log("");
|
|
4488
4807
|
try {
|
|
4489
4808
|
await callCloudFunction("registerRemoteDaemonSession", {
|
|
4490
|
-
conversationId
|
|
4809
|
+
conversationId,
|
|
4491
4810
|
sessionId,
|
|
4492
4811
|
machineId,
|
|
4493
4812
|
projectName,
|
|
@@ -4509,7 +4828,7 @@ async function startActiveBob(config, sessionId, machineId, projectName, tierCon
|
|
|
4509
4828
|
console.log(GRAY2(" \u{1F50C} Shutting down Active Bob..."));
|
|
4510
4829
|
try {
|
|
4511
4830
|
await callCloudFunction("deregisterRemoteDaemonSession", {
|
|
4512
|
-
conversationId
|
|
4831
|
+
conversationId,
|
|
4513
4832
|
sessionId
|
|
4514
4833
|
});
|
|
4515
4834
|
console.log(GRAY2(" \u2705 Session deregistered. Bob is offline."));
|
|
@@ -4530,12 +4849,12 @@ async function startActiveBob(config, sessionId, machineId, projectName, tierCon
|
|
|
4530
4849
|
const timeSinceLastCommand = Date.now() - lastCommandTime;
|
|
4531
4850
|
if (tierConfig.extendedIdleTimeout && timeSinceLastCommand > tierConfig.extendedIdleTimeout) {
|
|
4532
4851
|
console.log("");
|
|
4533
|
-
console.log(
|
|
4852
|
+
console.log(AMBER4(` \u23F8\uFE0F No commands received in ${Math.round(tierConfig.extendedIdleTimeout / 6e4)} minutes.`));
|
|
4534
4853
|
console.log(GRAY2(" Active Bob is going offline. Run `bob serve` to restart."));
|
|
4535
4854
|
console.log("");
|
|
4536
4855
|
try {
|
|
4537
4856
|
await callCloudFunction("deregisterRemoteDaemonSession", {
|
|
4538
|
-
conversationId
|
|
4857
|
+
conversationId,
|
|
4539
4858
|
sessionId
|
|
4540
4859
|
});
|
|
4541
4860
|
} catch {
|
|
@@ -4553,7 +4872,7 @@ async function startActiveBob(config, sessionId, machineId, projectName, tierCon
|
|
|
4553
4872
|
const currentInterval = isSleeping && tierConfig.sleepInterval ? tierConfig.sleepInterval : tierConfig.activeInterval;
|
|
4554
4873
|
try {
|
|
4555
4874
|
const result = await callCloudFunction("pollRemoteCommands", {
|
|
4556
|
-
conversationId
|
|
4875
|
+
conversationId,
|
|
4557
4876
|
sessionId
|
|
4558
4877
|
});
|
|
4559
4878
|
if (result?.command) {
|
|
@@ -4566,10 +4885,10 @@ async function startActiveBob(config, sessionId, machineId, projectName, tierCon
|
|
|
4566
4885
|
}
|
|
4567
4886
|
lastCommandTime = Date.now();
|
|
4568
4887
|
const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
4569
|
-
console.log(
|
|
4888
|
+
console.log(AMBER4(` [${timestamp}] \u23F3 Received: ${type}${payload.message ? ` "${payload.message.slice(0, 40)}${payload.message.length > 40 ? "..." : ""}"` : ""}`));
|
|
4570
4889
|
const commandResult = await executeRemoteCommand(type, payload, config);
|
|
4571
4890
|
await callCloudFunction("completeRemoteCommand", {
|
|
4572
|
-
conversationId
|
|
4891
|
+
conversationId,
|
|
4573
4892
|
commandId: cmd.id,
|
|
4574
4893
|
sessionId,
|
|
4575
4894
|
result: commandResult
|
|
@@ -5002,7 +5321,6 @@ async function executeRestore(payload, config) {
|
|
|
5002
5321
|
isGlobal,
|
|
5003
5322
|
isSource,
|
|
5004
5323
|
s3VersionId: null
|
|
5005
|
-
// always latest in headless mode
|
|
5006
5324
|
});
|
|
5007
5325
|
const response = await axios.get(downloadResult.downloadUrl, {
|
|
5008
5326
|
responseType: "arraybuffer",
|
|
@@ -5067,16 +5385,17 @@ function registerRemoteCommand(program2) {
|
|
|
5067
5385
|
console.log("");
|
|
5068
5386
|
return;
|
|
5069
5387
|
}
|
|
5070
|
-
|
|
5388
|
+
const activeConvoId = getActiveConversationId(process.cwd()) || config.conversationId;
|
|
5389
|
+
if (options.new || !activeConvoId) {
|
|
5071
5390
|
await discoverAndConnect(config);
|
|
5072
5391
|
return;
|
|
5073
5392
|
}
|
|
5074
5393
|
if (options.interactive || !type && !options.new) {
|
|
5075
|
-
await runInteractiveRemote(config, options.session);
|
|
5394
|
+
await runInteractiveRemote(config, activeConvoId, options.session);
|
|
5076
5395
|
return;
|
|
5077
5396
|
}
|
|
5078
5397
|
if (!type) {
|
|
5079
|
-
await showConnectionStatus(config);
|
|
5398
|
+
await showConnectionStatus(config, activeConvoId);
|
|
5080
5399
|
return;
|
|
5081
5400
|
}
|
|
5082
5401
|
const validTypes = [
|
|
@@ -5096,7 +5415,7 @@ function registerRemoteCommand(program2) {
|
|
|
5096
5415
|
console.log("");
|
|
5097
5416
|
return;
|
|
5098
5417
|
}
|
|
5099
|
-
const payload = { conversationId:
|
|
5418
|
+
const payload = { conversationId: activeConvoId };
|
|
5100
5419
|
if (message) payload.message = message;
|
|
5101
5420
|
if (options.auto) payload.auto = true;
|
|
5102
5421
|
if (options.source) payload.isSource = true;
|
|
@@ -5109,15 +5428,15 @@ function registerRemoteCommand(program2) {
|
|
|
5109
5428
|
console.log("");
|
|
5110
5429
|
return;
|
|
5111
5430
|
}
|
|
5112
|
-
await dispatchCommand(config, type, payload, options.session);
|
|
5431
|
+
await dispatchCommand(config, activeConvoId, type, payload, options.session);
|
|
5113
5432
|
});
|
|
5114
5433
|
}
|
|
5115
|
-
async function runInteractiveRemote(config, targetSession) {
|
|
5434
|
+
async function runInteractiveRemote(config, activeConvoId, targetSession) {
|
|
5116
5435
|
const spinner = ora7({ text: INFO14(" Connecting to Active Bob..."), spinner: "dots" }).start();
|
|
5117
5436
|
let activeBobName = "Unknown";
|
|
5118
5437
|
try {
|
|
5119
5438
|
const result = await callCloudFunction("listActiveBobs", {
|
|
5120
|
-
conversationId:
|
|
5439
|
+
conversationId: activeConvoId
|
|
5121
5440
|
});
|
|
5122
5441
|
const sessions = (result?.sessions || []).filter((s) => s.active);
|
|
5123
5442
|
if (sessions.length === 0) {
|
|
@@ -5139,7 +5458,7 @@ async function runInteractiveRemote(config, targetSession) {
|
|
|
5139
5458
|
console.log(BORDER6(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
5140
5459
|
console.log(BORDER6(" \u2551") + INFO14(" \u{1F310} Active Bob \u2014 Remote Session") + MUTED14(` (${activeBobName})`));
|
|
5141
5460
|
console.log(BORDER6(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
5142
|
-
console.log(BORDER6(" \u2551") + MUTED14(` Conversation: ${
|
|
5461
|
+
console.log(BORDER6(" \u2551") + MUTED14(` Conversation: ${activeConvoId?.slice(0, 28)}...`));
|
|
5143
5462
|
console.log(BORDER6(" \u2551") + MUTED14(" Commands dispatched to the remote machine."));
|
|
5144
5463
|
console.log(BORDER6(" \u2551"));
|
|
5145
5464
|
console.log(BORDER6(" \u2551") + chalk20.white(" Slash Commands:"));
|
|
@@ -5176,7 +5495,7 @@ async function runInteractiveRemote(config, targetSession) {
|
|
|
5176
5495
|
if (trimmed.startsWith("/consult ")) {
|
|
5177
5496
|
const msg = trimmed.slice(9).trim().replace(/^["']|["']$/g, "");
|
|
5178
5497
|
if (msg) {
|
|
5179
|
-
await dispatchAndShow(config, "consult", { message: msg }, targetSession);
|
|
5498
|
+
await dispatchAndShow(config, activeConvoId, "consult", { message: msg }, targetSession);
|
|
5180
5499
|
} else {
|
|
5181
5500
|
console.log(ERROR12(' \u274C Provide a message: /consult "your question"'));
|
|
5182
5501
|
}
|
|
@@ -5186,7 +5505,7 @@ async function runInteractiveRemote(config, targetSession) {
|
|
|
5186
5505
|
if (trimmed.startsWith("/push ")) {
|
|
5187
5506
|
const msg = trimmed.slice(6).trim().replace(/^["']|["']$/g, "");
|
|
5188
5507
|
if (msg) {
|
|
5189
|
-
await dispatchAndShow(config, "push", { message: msg }, targetSession);
|
|
5508
|
+
await dispatchAndShow(config, activeConvoId, "push", { message: msg }, targetSession);
|
|
5190
5509
|
} else {
|
|
5191
5510
|
console.log(ERROR12(' \u274C Provide a commit message: /push "your message"'));
|
|
5192
5511
|
}
|
|
@@ -5194,12 +5513,12 @@ async function runInteractiveRemote(config, targetSession) {
|
|
|
5194
5513
|
return;
|
|
5195
5514
|
}
|
|
5196
5515
|
if (trimmed === "/index") {
|
|
5197
|
-
await dispatchAndShow(config, "index", {}, targetSession);
|
|
5516
|
+
await dispatchAndShow(config, activeConvoId, "index", {}, targetSession);
|
|
5198
5517
|
prompt();
|
|
5199
5518
|
return;
|
|
5200
5519
|
}
|
|
5201
5520
|
if (trimmed === "/analyse" || trimmed === "/analyze") {
|
|
5202
|
-
await dispatchAndShow(config, "analyse", {}, targetSession);
|
|
5521
|
+
await dispatchAndShow(config, activeConvoId, "analyse", {}, targetSession);
|
|
5203
5522
|
prompt();
|
|
5204
5523
|
return;
|
|
5205
5524
|
}
|
|
@@ -5209,7 +5528,7 @@ async function runInteractiveRemote(config, targetSession) {
|
|
|
5209
5528
|
const backupPayload = {};
|
|
5210
5529
|
if (flag === "source") backupPayload.isSource = true;
|
|
5211
5530
|
if (flag === "global") backupPayload.isGlobal = true;
|
|
5212
|
-
await dispatchAndShow(config, "backup", backupPayload, targetSession);
|
|
5531
|
+
await dispatchAndShow(config, activeConvoId, "backup", backupPayload, targetSession);
|
|
5213
5532
|
prompt();
|
|
5214
5533
|
return;
|
|
5215
5534
|
}
|
|
@@ -5219,17 +5538,17 @@ async function runInteractiveRemote(config, targetSession) {
|
|
|
5219
5538
|
const restorePayload = {};
|
|
5220
5539
|
if (flag === "source") restorePayload.isSource = true;
|
|
5221
5540
|
if (flag === "global") restorePayload.isGlobal = true;
|
|
5222
|
-
await dispatchAndShow(config, "restore", restorePayload, targetSession);
|
|
5541
|
+
await dispatchAndShow(config, activeConvoId, "restore", restorePayload, targetSession);
|
|
5223
5542
|
prompt();
|
|
5224
5543
|
return;
|
|
5225
5544
|
}
|
|
5226
|
-
await dispatchAndShow(config, "chat", { message: trimmed }, targetSession);
|
|
5545
|
+
await dispatchAndShow(config, activeConvoId, "chat", { message: trimmed }, targetSession);
|
|
5227
5546
|
prompt();
|
|
5228
5547
|
});
|
|
5229
5548
|
};
|
|
5230
5549
|
prompt();
|
|
5231
5550
|
}
|
|
5232
|
-
async function dispatchAndShow(config, type, payload, targetSession) {
|
|
5551
|
+
async function dispatchAndShow(config, activeConvoId, type, payload, targetSession) {
|
|
5233
5552
|
const spinner = ora7({
|
|
5234
5553
|
text: BRAND_SECONDARY13(` \u{1F4E1} Active Bob executing: ${type}...`),
|
|
5235
5554
|
spinner: "dots"
|
|
@@ -5238,9 +5557,9 @@ async function dispatchAndShow(config, type, payload, targetSession) {
|
|
|
5238
5557
|
const MAX_POLLS = 300;
|
|
5239
5558
|
try {
|
|
5240
5559
|
const result = await callCloudFunction("sendRemoteCommand", {
|
|
5241
|
-
conversationId:
|
|
5560
|
+
conversationId: activeConvoId,
|
|
5242
5561
|
type,
|
|
5243
|
-
payload: { ...payload, conversationId:
|
|
5562
|
+
payload: { ...payload, conversationId: activeConvoId },
|
|
5244
5563
|
targetSession: targetSession || null
|
|
5245
5564
|
});
|
|
5246
5565
|
if (!result?.success) {
|
|
@@ -5254,7 +5573,7 @@ async function dispatchAndShow(config, type, payload, targetSession) {
|
|
|
5254
5573
|
pollCount++;
|
|
5255
5574
|
try {
|
|
5256
5575
|
const pollResult = await callCloudFunction("getRemoteCommandResult", {
|
|
5257
|
-
conversationId:
|
|
5576
|
+
conversationId: activeConvoId,
|
|
5258
5577
|
commandId
|
|
5259
5578
|
});
|
|
5260
5579
|
if (pollResult?.status === "completed") {
|
|
@@ -5313,17 +5632,10 @@ async function dispatchAndShow(config, type, payload, targetSession) {
|
|
|
5313
5632
|
console.log("");
|
|
5314
5633
|
}
|
|
5315
5634
|
}
|
|
5316
|
-
async function showConnectionStatus(config) {
|
|
5317
|
-
if (!config.conversationId) {
|
|
5318
|
-
console.log("");
|
|
5319
|
-
console.log(ERROR12(" \u{1F534} No conversation selected."));
|
|
5320
|
-
console.log(MUTED14(" Run `bob remote --new` to find and connect to an Active Bob."));
|
|
5321
|
-
console.log("");
|
|
5322
|
-
return;
|
|
5323
|
-
}
|
|
5635
|
+
async function showConnectionStatus(config, activeConvoId) {
|
|
5324
5636
|
const spinner = ora7({ text: INFO14(" Checking Active Bob status..."), spinner: "dots" }).start();
|
|
5325
5637
|
try {
|
|
5326
|
-
const result = await callCloudFunction("listActiveBobs", { conversationId:
|
|
5638
|
+
const result = await callCloudFunction("listActiveBobs", { conversationId: activeConvoId });
|
|
5327
5639
|
spinner.stop();
|
|
5328
5640
|
const sessions = result?.sessions || [];
|
|
5329
5641
|
const activeSessions = sessions.filter((s) => s.active);
|
|
@@ -5331,7 +5643,7 @@ async function showConnectionStatus(config) {
|
|
|
5331
5643
|
console.log(BORDER6(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
5332
5644
|
console.log(BORDER6(" \u2551") + INFO14(" \u{1F310} Remote Connection Status"));
|
|
5333
5645
|
console.log(BORDER6(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
5334
|
-
console.log(BORDER6(" \u2551") + MUTED14(` Conversation: ${
|
|
5646
|
+
console.log(BORDER6(" \u2551") + MUTED14(` Conversation: ${activeConvoId?.slice(0, 28)}...`));
|
|
5335
5647
|
console.log(BORDER6(" \u2551"));
|
|
5336
5648
|
if (activeSessions.length === 0) {
|
|
5337
5649
|
console.log(BORDER6(" \u2551") + ERROR12(" \u{1F534} No Active Bob found on this conversation."));
|
|
@@ -5415,8 +5727,8 @@ async function discoverAndConnect(config) {
|
|
|
5415
5727
|
console.log("");
|
|
5416
5728
|
}
|
|
5417
5729
|
}
|
|
5418
|
-
async function dispatchCommand(config, type, payload, targetSession) {
|
|
5419
|
-
await dispatchAndShow(config, type, payload, targetSession);
|
|
5730
|
+
async function dispatchCommand(config, activeConvoId, type, payload, targetSession) {
|
|
5731
|
+
await dispatchAndShow(config, activeConvoId, type, payload, targetSession);
|
|
5420
5732
|
}
|
|
5421
5733
|
function getTimeAgo2(isoDate) {
|
|
5422
5734
|
const now = Date.now();
|
|
@@ -5437,7 +5749,7 @@ import ora10 from "ora";
|
|
|
5437
5749
|
// src/core/cloud-profiler.ts
|
|
5438
5750
|
import chalk21 from "chalk";
|
|
5439
5751
|
import ora8 from "ora";
|
|
5440
|
-
var
|
|
5752
|
+
var AMBER5 = chalk21.hex("#FFAB00");
|
|
5441
5753
|
var ORANGE = chalk21.hex("#E66F24");
|
|
5442
5754
|
var GREEN3 = chalk21.hex("#66BB6A");
|
|
5443
5755
|
var CYAN3 = chalk21.cyan;
|
|
@@ -5461,7 +5773,7 @@ function renderProgressBar(score, width = 30) {
|
|
|
5461
5773
|
function renderChunkBar(current, total, width = 30) {
|
|
5462
5774
|
const filled = Math.round(current / total * width);
|
|
5463
5775
|
const empty = width - filled;
|
|
5464
|
-
return
|
|
5776
|
+
return AMBER5("\u2588".repeat(filled)) + chalk21.hex("#333333")("\u2591".repeat(empty)) + GRAY3(` ${current}/${total}`);
|
|
5465
5777
|
}
|
|
5466
5778
|
function truncate2(text, max) {
|
|
5467
5779
|
if (!text) return "";
|
|
@@ -5508,7 +5820,7 @@ async function runCloudProfiler(options) {
|
|
|
5508
5820
|
throw new Error("Cloud profiling requires authentication. Run `bob login` first.");
|
|
5509
5821
|
}
|
|
5510
5822
|
console.log("");
|
|
5511
|
-
console.log(
|
|
5823
|
+
console.log(AMBER5(` \u{1F9EC} Running cloud ${scope} profiling (Power tier)...`));
|
|
5512
5824
|
console.log("");
|
|
5513
5825
|
const spinner = ora8({ text: CYAN3(" Initiating profiling job..."), spinner: "dots" }).start();
|
|
5514
5826
|
const startResult = await callCloudFunction("startCloudProfiling", {
|
|
@@ -5669,7 +5981,7 @@ async function runCloudProfiler(options) {
|
|
|
5669
5981
|
const archetype = archMatch ? archMatch[1].trim() : "profiled";
|
|
5670
5982
|
const description = descMatch ? truncate2(descMatch[1].trim(), 50) : "";
|
|
5671
5983
|
renderBox("\u{1F3AF}", "Stage 4: Decision Profile", [
|
|
5672
|
-
`${GRAY3("Archetype:")} ${
|
|
5984
|
+
`${GRAY3("Archetype:")} ${AMBER5(archetype)}`,
|
|
5673
5985
|
description ? `${GRAY3('"' + description + '"')}` : ""
|
|
5674
5986
|
].filter(Boolean));
|
|
5675
5987
|
stage4Rendered = true;
|
|
@@ -5720,7 +6032,7 @@ async function runCloudProfiler(options) {
|
|
|
5720
6032
|
const archetype = archMatch ? archMatch[1].trim() : "profiled";
|
|
5721
6033
|
const edge = edgeMatch ? parseInt(edgeMatch[1]) : 0;
|
|
5722
6034
|
renderBox("\u{1F3AF}", "Weekly Decision Profile", [
|
|
5723
|
-
`${GRAY3("Archetype:")} ${
|
|
6035
|
+
`${GRAY3("Archetype:")} ${AMBER5(archetype)}`,
|
|
5724
6036
|
`${GRAY3("Edge Score:")} ${renderProgressBar(edge)}`
|
|
5725
6037
|
]);
|
|
5726
6038
|
weeklyDecisionRendered = true;
|
|
@@ -5738,7 +6050,7 @@ async function runCloudProfiler(options) {
|
|
|
5738
6050
|
const synthMatch = msg.match(/Weekly synthesis complete: (.+)/);
|
|
5739
6051
|
const synthesis = synthMatch ? truncate2(synthMatch[1].trim(), 50) : "synthesized";
|
|
5740
6052
|
renderBox("\u{1F9EC}", "Weekly DNA Synthesis", [
|
|
5741
|
-
`${GRAY3("Archetype:")} ${
|
|
6053
|
+
`${GRAY3("Archetype:")} ${AMBER5(synthesis)}`,
|
|
5742
6054
|
`${GRAY3("Your weekly personality profile has been updated.")}`
|
|
5743
6055
|
]);
|
|
5744
6056
|
weeklySynthesisRendered = true;
|
|
@@ -5770,7 +6082,7 @@ async function runCloudProfiler(options) {
|
|
|
5770
6082
|
const archMatch = msg.match(/Monthly synthesis complete: (.+)/);
|
|
5771
6083
|
const archetype = archMatch ? truncate2(archMatch[1].trim(), 50) : "synthesized";
|
|
5772
6084
|
renderBox("\u{1F9EC}", "Monthly DNA Synthesis", [
|
|
5773
|
-
`${GRAY3("Monthly Archetype:")} ${
|
|
6085
|
+
`${GRAY3("Monthly Archetype:")} ${AMBER5(archetype)}`,
|
|
5774
6086
|
`${GRAY3("Your complete monthly personality profile is now active.")}`,
|
|
5775
6087
|
`${GRAY3("Bob will adapt to match your patterns going forward.")}`
|
|
5776
6088
|
]);
|
|
@@ -6098,7 +6410,7 @@ async function renderProfileDashboard() {
|
|
|
6098
6410
|
|
|
6099
6411
|
// src/commands/profile.ts
|
|
6100
6412
|
import * as path11 from "path";
|
|
6101
|
-
var
|
|
6413
|
+
var AMBER6 = chalk23.hex("#FFAB00");
|
|
6102
6414
|
var GREEN4 = chalk23.hex("#66BB6A");
|
|
6103
6415
|
var BLUE2 = chalk23.hex("#42A5F5");
|
|
6104
6416
|
var GRAY4 = chalk23.gray;
|
|
@@ -6156,7 +6468,7 @@ async function handleCloudProfile(scope) {
|
|
|
6156
6468
|
return;
|
|
6157
6469
|
}
|
|
6158
6470
|
console.log("");
|
|
6159
|
-
console.log(
|
|
6471
|
+
console.log(AMBER6(` \u{1F9EC} Running cloud ${scope} profiling (Power tier)...`));
|
|
6160
6472
|
console.log("");
|
|
6161
6473
|
try {
|
|
6162
6474
|
await runCloudProfiler({
|
|
@@ -6193,14 +6505,14 @@ function showCurrentProfile() {
|
|
|
6193
6505
|
const dna = loadCurrentDNA();
|
|
6194
6506
|
if (!dna) {
|
|
6195
6507
|
console.log("");
|
|
6196
|
-
console.log(
|
|
6508
|
+
console.log(AMBER6(" \u26A0\uFE0F No profile generated yet."));
|
|
6197
6509
|
console.log(GRAY4(" Run `bob profile --today` to generate your first profile."));
|
|
6198
6510
|
console.log("");
|
|
6199
6511
|
return;
|
|
6200
6512
|
}
|
|
6201
6513
|
console.log("");
|
|
6202
6514
|
console.log(BORDER9(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
6203
|
-
console.log(BORDER9(" \u2551") +
|
|
6515
|
+
console.log(BORDER9(" \u2551") + AMBER6(" \u{1F9EC} Your Current DNA Profile"));
|
|
6204
6516
|
console.log(BORDER9(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
6205
6517
|
console.log(BORDER9(" \u2551") + CYAN4(` Archetype: ${dna.archetype || "Unknown"}`));
|
|
6206
6518
|
console.log(BORDER9(" \u2551") + GRAY4(` Communication: ${dna.communicationStyle || "Unknown"}`));
|
|
@@ -6227,7 +6539,7 @@ async function generateDailyProfile(config) {
|
|
|
6227
6539
|
const messages = await getTodayMessages();
|
|
6228
6540
|
if (messages.length === 0) {
|
|
6229
6541
|
console.log("");
|
|
6230
|
-
console.log(
|
|
6542
|
+
console.log(AMBER6(" \u26A0\uFE0F No conversations found for today."));
|
|
6231
6543
|
console.log(GRAY4(" Chat with Bob first, then run this command."));
|
|
6232
6544
|
console.log("");
|
|
6233
6545
|
return;
|
|
@@ -6322,7 +6634,7 @@ IMPORTANT: Only include assessments you have EVIDENCE for. Use exact quotes from
|
|
|
6322
6634
|
saveDailyProfile(profile);
|
|
6323
6635
|
console.log("");
|
|
6324
6636
|
console.log(BORDER9(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
6325
|
-
console.log(BORDER9(" \u2551") +
|
|
6637
|
+
console.log(BORDER9(" \u2551") + AMBER6(` \u{1F9EC} Daily Profile \u2014 ${today}`));
|
|
6326
6638
|
console.log(BORDER9(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
6327
6639
|
console.log(BORDER9(" \u2551") + CYAN4(` Communication: ${parsed.communicationStyle?.tone || "Unknown"} (${parsed.communicationStyle?.confidence || 0}%)`));
|
|
6328
6640
|
console.log(BORDER9(" \u2551") + CYAN4(` Mentality: ${parsed.mentality?.approach || "Unknown"}, ${parsed.mentality?.optimism || ""} (${parsed.mentality?.confidence || 0}%)`));
|
|
@@ -6349,7 +6661,7 @@ async function generateWeeklyProfile(config) {
|
|
|
6349
6661
|
const dailies = loadDailyProfiles(7);
|
|
6350
6662
|
if (dailies.length === 0) {
|
|
6351
6663
|
console.log("");
|
|
6352
|
-
console.log(
|
|
6664
|
+
console.log(AMBER6(" \u26A0\uFE0F No daily profiles found."));
|
|
6353
6665
|
console.log(GRAY4(" Run `bob profile --today` for at least a few days first."));
|
|
6354
6666
|
console.log("");
|
|
6355
6667
|
return;
|
|
@@ -6411,7 +6723,7 @@ Use REAL quotes from the daily profiles as evidence. Show how the person CHANGED
|
|
|
6411
6723
|
saveWeeklyProfile(profile);
|
|
6412
6724
|
console.log("");
|
|
6413
6725
|
console.log(BORDER9(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
6414
|
-
console.log(BORDER9(" \u2551") +
|
|
6726
|
+
console.log(BORDER9(" \u2551") + AMBER6(` \u{1F9EC} Weekly Profile \u2014 ${weekId}`));
|
|
6415
6727
|
console.log(BORDER9(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
6416
6728
|
console.log(BORDER9(" \u2551") + CYAN4(` Trajectory: ${parsed.trajectory || "Unknown"}`));
|
|
6417
6729
|
console.log(BORDER9(" \u2551") + GRAY4(` Energy: ${parsed.energyPattern || "Unknown"}`));
|
|
@@ -6440,7 +6752,7 @@ async function generateMonthlyProfile(config) {
|
|
|
6440
6752
|
const weeklies = loadWeeklyProfiles(5);
|
|
6441
6753
|
if (dailies.length === 0 && weeklies.length === 0) {
|
|
6442
6754
|
console.log("");
|
|
6443
|
-
console.log(
|
|
6755
|
+
console.log(AMBER6(" \u26A0\uFE0F No profiles found for this month."));
|
|
6444
6756
|
console.log(GRAY4(" Run `bob profile --today` daily and `bob profile --week` weekly first."));
|
|
6445
6757
|
console.log("");
|
|
6446
6758
|
return;
|
|
@@ -6510,7 +6822,7 @@ Show the JOURNEY, not just the destination. Use real quotes as evidence for ever
|
|
|
6510
6822
|
saveMonthlyProfile(profile);
|
|
6511
6823
|
console.log("");
|
|
6512
6824
|
console.log(BORDER9(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
6513
|
-
console.log(BORDER9(" \u2551") +
|
|
6825
|
+
console.log(BORDER9(" \u2551") + AMBER6(` \u{1F9EC} Monthly Profile \u2014 ${monthId}`));
|
|
6514
6826
|
console.log(BORDER9(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
6515
6827
|
console.log(BORDER9(" \u2551") + CYAN4(` Archetype: ${parsed.personalitySnapshot?.archetype || "Unknown"}`));
|
|
6516
6828
|
console.log(BORDER9(" \u2551"));
|
|
@@ -6564,7 +6876,7 @@ var BRAND = chalk24.hex("#E66F24");
|
|
|
6564
6876
|
var CYAN5 = chalk24.cyan;
|
|
6565
6877
|
var GREEN5 = chalk24.hex("#66BB6A");
|
|
6566
6878
|
var RED5 = chalk24.hex("#EF5350");
|
|
6567
|
-
var
|
|
6879
|
+
var AMBER7 = chalk24.hex("#FFAB00");
|
|
6568
6880
|
var GRAY5 = chalk24.gray;
|
|
6569
6881
|
var BORDER10 = chalk24.hex("#455A64");
|
|
6570
6882
|
var BOB_DIR3 = path12.join(os3.homedir(), ".bob");
|
|
@@ -6632,19 +6944,19 @@ function normalizeFilePath(filePath) {
|
|
|
6632
6944
|
function handleBackupError(error) {
|
|
6633
6945
|
if (error.message?.includes("BOB_BACKUP_LICENSE_REQUIRED")) {
|
|
6634
6946
|
console.log("");
|
|
6635
|
-
console.log(
|
|
6947
|
+
console.log(AMBER7(" \u26A0\uFE0F No active backup license found."));
|
|
6636
6948
|
console.log(GRAY5(" Purchase one at: app.bobsworkshop.com/iap \u2192 Bob Backup"));
|
|
6637
6949
|
} else if (error.message?.includes("STORAGE_QUOTA_EXCEEDED")) {
|
|
6638
6950
|
console.log("");
|
|
6639
|
-
console.log(
|
|
6951
|
+
console.log(AMBER7(" \u26A0\uFE0F Storage quota exceeded."));
|
|
6640
6952
|
console.log(GRAY5(" Purchase a storage pack: app.bobsworkshop.com/iap \u2192 Storage Packs"));
|
|
6641
6953
|
} else if (error.message?.includes("ARCHIVE_SLOTS_EXHAUSTED")) {
|
|
6642
6954
|
console.log("");
|
|
6643
|
-
console.log(
|
|
6955
|
+
console.log(AMBER7(" \u26A0\uFE0F All archive slots are used."));
|
|
6644
6956
|
console.log(GRAY5(" Upgrade your Workshop SKU for more archive slots."));
|
|
6645
6957
|
} else if (error.message?.includes("GRID_REQUIRED")) {
|
|
6646
6958
|
console.log("");
|
|
6647
|
-
console.log(
|
|
6959
|
+
console.log(AMBER7(" \u26A0\uFE0F Global backup requires the Grid Workshop plan."));
|
|
6648
6960
|
console.log(GRAY5(" Upgrade at: app.bobsworkshop.com/iap \u2192 Workshop"));
|
|
6649
6961
|
} else {
|
|
6650
6962
|
console.log("");
|
|
@@ -6782,7 +7094,7 @@ async function runBackup(options) {
|
|
|
6782
7094
|
}
|
|
6783
7095
|
recordSpinner.succeed(GREEN5(" Recording usage ..."));
|
|
6784
7096
|
} catch {
|
|
6785
|
-
recordSpinner.warn(
|
|
7097
|
+
recordSpinner.warn(AMBER7(" Usage recording failed (non-fatal). Backup was saved."));
|
|
6786
7098
|
}
|
|
6787
7099
|
const now = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
6788
7100
|
console.log(BORDER10(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
@@ -6907,7 +7219,7 @@ async function runSourceBackup(options) {
|
|
|
6907
7219
|
await callCloudFunction("cliBackupLicense", recordPayload);
|
|
6908
7220
|
recordSpinner.succeed(GREEN5(" Recording usage ..."));
|
|
6909
7221
|
} catch {
|
|
6910
|
-
recordSpinner.warn(
|
|
7222
|
+
recordSpinner.warn(AMBER7(" Usage recording failed (non-fatal). Backup was saved."));
|
|
6911
7223
|
}
|
|
6912
7224
|
const now = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
6913
7225
|
console.log(BORDER10(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
@@ -7007,12 +7319,12 @@ function registerBackupCommand(program2) {
|
|
|
7007
7319
|
}
|
|
7008
7320
|
if (archives.length > 0) {
|
|
7009
7321
|
console.log(BORDER10(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
7010
|
-
console.log(BORDER10(" \u2551") +
|
|
7322
|
+
console.log(BORDER10(" \u2551") + AMBER7(" Named Archives"));
|
|
7011
7323
|
console.log(BORDER10(" \u2551") + GRAY5(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
7012
7324
|
for (const a of archives) {
|
|
7013
7325
|
const date = new Date(a.createdAt).toLocaleString();
|
|
7014
7326
|
const expires = new Date(a.expiresAt).toLocaleString();
|
|
7015
|
-
console.log(BORDER10(" \u2551") + ` \u{1F4CC} ${
|
|
7327
|
+
console.log(BORDER10(" \u2551") + ` \u{1F4CC} ${AMBER7(a.name.padEnd(24))} ${GRAY5(formatBytes(a.sizeGB * 1024 * 1024 * 1024))}`);
|
|
7016
7328
|
console.log(BORDER10(" \u2551") + GRAY5(` Created: ${date} | Expires: ${expires}`));
|
|
7017
7329
|
}
|
|
7018
7330
|
}
|
|
@@ -7059,7 +7371,7 @@ function registerBackupCommand(program2) {
|
|
|
7059
7371
|
if (versions.length === 0 && archives.length === 0) {
|
|
7060
7372
|
console.log("");
|
|
7061
7373
|
const scopeMsg = isSource ? filePath ? `file "${filePath}"` : `source of ${projectName}` : isGlobal ? "global" : projectName;
|
|
7062
|
-
console.log(
|
|
7374
|
+
console.log(AMBER7(` \u26A0\uFE0F No backups found for ${scopeMsg}.`));
|
|
7063
7375
|
console.log("");
|
|
7064
7376
|
return;
|
|
7065
7377
|
}
|
|
@@ -7075,11 +7387,11 @@ function registerBackupCommand(program2) {
|
|
|
7075
7387
|
}
|
|
7076
7388
|
}
|
|
7077
7389
|
if (archives.length > 0) {
|
|
7078
|
-
choices.push(new inquirer.Separator(
|
|
7390
|
+
choices.push(new inquirer.Separator(AMBER7(" \u2500\u2500 Named Archives \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")));
|
|
7079
7391
|
for (const a of archives) {
|
|
7080
7392
|
const date = new Date(a.createdAt).toLocaleString();
|
|
7081
7393
|
choices.push({
|
|
7082
|
-
name: ` \u{1F4CC} ${
|
|
7394
|
+
name: ` \u{1F4CC} ${AMBER7(a.name.padEnd(24))} ${GRAY5(date)}`,
|
|
7083
7395
|
value: { type: "archive", archiveId: a.archiveId, name: a.name }
|
|
7084
7396
|
});
|
|
7085
7397
|
}
|
|
@@ -7103,20 +7415,20 @@ function registerBackupCommand(program2) {
|
|
|
7103
7415
|
const label = selected.type === "archive" ? `archive "${selected.name}"` : selected.label;
|
|
7104
7416
|
console.log("");
|
|
7105
7417
|
if (isSource && filePath) {
|
|
7106
|
-
console.log(
|
|
7418
|
+
console.log(AMBER7(` \u26A0\uFE0F This will restore ${filePath} from ${label}.`));
|
|
7107
7419
|
console.log(GRAY5(" Current file will be backed up to .bob-backups/ first."));
|
|
7108
7420
|
} else if (isSource) {
|
|
7109
|
-
console.log(
|
|
7421
|
+
console.log(AMBER7(` \u26A0\uFE0F This will restore source code of ${projectName} from ${label}.`));
|
|
7110
7422
|
console.log(GRAY5(" Current project will be backed up locally first."));
|
|
7111
7423
|
} else {
|
|
7112
|
-
console.log(
|
|
7424
|
+
console.log(AMBER7(` \u26A0\uFE0F This will restore ${isGlobal ? "~/.bob/" : `~/.bob/projects/${projectName}/`} from ${label}.`));
|
|
7113
7425
|
console.log(GRAY5(" Your current data will be backed up locally first."));
|
|
7114
7426
|
}
|
|
7115
7427
|
console.log("");
|
|
7116
7428
|
const { confirmed } = await inquirer.prompt([{
|
|
7117
7429
|
type: "confirm",
|
|
7118
7430
|
name: "confirmed",
|
|
7119
|
-
message:
|
|
7431
|
+
message: AMBER7(" Continue with restore?"),
|
|
7120
7432
|
default: false
|
|
7121
7433
|
}]);
|
|
7122
7434
|
if (!confirmed) {
|
|
@@ -7515,7 +7827,7 @@ ${userMessage}`,
|
|
|
7515
7827
|
// src/ui/agent-renderer.ts
|
|
7516
7828
|
import chalk25 from "chalk";
|
|
7517
7829
|
var PURPLE = chalk25.hex("#AB47BC");
|
|
7518
|
-
var
|
|
7830
|
+
var AMBER8 = chalk25.hex("#FFAB00");
|
|
7519
7831
|
var GREEN6 = chalk25.hex("#66BB6A");
|
|
7520
7832
|
var RED6 = chalk25.hex("#EF5350");
|
|
7521
7833
|
var CYAN6 = chalk25.cyan;
|
|
@@ -7713,7 +8025,7 @@ function renderUnifiedMessages(messages, allAgentNames, options = {}) {
|
|
|
7713
8025
|
console.log("");
|
|
7714
8026
|
console.log(BORDER11(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
7715
8027
|
console.log(
|
|
7716
|
-
BORDER11(" \u2551") +
|
|
8028
|
+
BORDER11(" \u2551") + AMBER8(" \u{1F4CB} Messages") + GRAY6(
|
|
7717
8029
|
` ${totalMessages} total` + (options.filterAgent ? ` filter: @${options.filterAgent}` : "") + (options.search ? ` search: "${options.search}"` : "")
|
|
7718
8030
|
)
|
|
7719
8031
|
);
|
|
@@ -7813,7 +8125,7 @@ async function runMessagesView(agentNames, cwd, rl, initialFilter, initialSearch
|
|
|
7813
8125
|
render();
|
|
7814
8126
|
return new Promise((resolve4) => {
|
|
7815
8127
|
const messagesPrompt = () => {
|
|
7816
|
-
rl.question(
|
|
8128
|
+
rl.question(AMBER8(" Messages > "), async (input) => {
|
|
7817
8129
|
const trimmed = input.trim();
|
|
7818
8130
|
if (!trimmed) {
|
|
7819
8131
|
messagesPrompt();
|
|
@@ -7894,7 +8206,7 @@ async function runAgentHub(cwd) {
|
|
|
7894
8206
|
const registry = loadRegistry(cwd);
|
|
7895
8207
|
if (registry.agents.length === 0) {
|
|
7896
8208
|
console.log("");
|
|
7897
|
-
console.log(
|
|
8209
|
+
console.log(AMBER8(" \u26A0\uFE0F No agents found."));
|
|
7898
8210
|
console.log(GRAY6(' Spawn one first: bob agent spawn <name> "<task>"'));
|
|
7899
8211
|
console.log("");
|
|
7900
8212
|
return;
|
|
@@ -7951,7 +8263,7 @@ async function runAgentHub(cwd) {
|
|
|
7951
8263
|
}
|
|
7952
8264
|
if (parsed.type === "unknown") {
|
|
7953
8265
|
console.log("");
|
|
7954
|
-
console.log(
|
|
8266
|
+
console.log(AMBER8(" \u26A0\uFE0F Use @name to talk to an agent."));
|
|
7955
8267
|
console.log(GRAY6(` Available: ${agentNames.map((n) => `@${n}`).join(", ")}`));
|
|
7956
8268
|
console.log(GRAY6(" Or use @all to broadcast to everyone."));
|
|
7957
8269
|
console.log("");
|
|
@@ -7959,7 +8271,7 @@ async function runAgentHub(cwd) {
|
|
|
7959
8271
|
return;
|
|
7960
8272
|
}
|
|
7961
8273
|
if (!parsed.message) {
|
|
7962
|
-
console.log(
|
|
8274
|
+
console.log(AMBER8(" \u26A0\uFE0F Message cannot be empty."));
|
|
7963
8275
|
prompt();
|
|
7964
8276
|
return;
|
|
7965
8277
|
}
|
|
@@ -7982,7 +8294,7 @@ async function runAgentHub(cwd) {
|
|
|
7982
8294
|
renderAgentResponse(targetName, result.response, agentColor);
|
|
7983
8295
|
if (result.summaryGenerated && result.summary) {
|
|
7984
8296
|
console.log("");
|
|
7985
|
-
console.log(
|
|
8297
|
+
console.log(AMBER8(` \u{1F9EC} @${targetName} session summarized (${result.messageCount} messages)`));
|
|
7986
8298
|
console.log(GRAY6(" Summary saved. Other agents will see this context."));
|
|
7987
8299
|
console.log(GRAY6(" View with: /summary"));
|
|
7988
8300
|
}
|
|
@@ -8172,7 +8484,7 @@ async function runAgentChat(agentName, cwd, initialSearch) {
|
|
|
8172
8484
|
const summary = loadAgentSummary2(agentName, cwd);
|
|
8173
8485
|
console.log("");
|
|
8174
8486
|
if (summary) {
|
|
8175
|
-
console.log(
|
|
8487
|
+
console.log(AMBER8(` \u{1F9EC} @${agentName} Summary`));
|
|
8176
8488
|
console.log(GRAY6(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
8177
8489
|
const lines = summary.split("\n").filter((l) => l.trim());
|
|
8178
8490
|
for (const line of lines) {
|
|
@@ -8240,7 +8552,7 @@ async function runAgentChat(agentName, cwd, initialSearch) {
|
|
|
8240
8552
|
renderAgentResponse(agentName, result.response, agentColor);
|
|
8241
8553
|
if (result.summaryGenerated && result.summary) {
|
|
8242
8554
|
console.log("");
|
|
8243
|
-
console.log(
|
|
8555
|
+
console.log(AMBER8(` \u{1F9EC} Session summarized (${result.messageCount} messages)`));
|
|
8244
8556
|
const lines = result.summary.split("\n").filter((l) => l.trim()).slice(0, 5);
|
|
8245
8557
|
for (const line of lines) {
|
|
8246
8558
|
console.log(GRAY6(` ${line.slice(0, 62)}`));
|
|
@@ -8263,7 +8575,7 @@ async function runAgentChat(agentName, cwd, initialSearch) {
|
|
|
8263
8575
|
|
|
8264
8576
|
// src/commands/agent.ts
|
|
8265
8577
|
var PURPLE3 = chalk28.hex("#AB47BC");
|
|
8266
|
-
var
|
|
8578
|
+
var AMBER9 = chalk28.hex("#FFAB00");
|
|
8267
8579
|
var GREEN8 = chalk28.hex("#66BB6A");
|
|
8268
8580
|
var RED7 = chalk28.hex("#EF5350");
|
|
8269
8581
|
var CYAN8 = chalk28.cyan;
|
|
@@ -8295,7 +8607,7 @@ function statusIcon(status) {
|
|
|
8295
8607
|
case "active":
|
|
8296
8608
|
return GREEN8("\u25CF");
|
|
8297
8609
|
case "idle":
|
|
8298
|
-
return
|
|
8610
|
+
return AMBER9("\u25CF");
|
|
8299
8611
|
case "stopped":
|
|
8300
8612
|
return GRAY7("\u25CB");
|
|
8301
8613
|
default:
|
|
@@ -8307,7 +8619,7 @@ function statusLabel(status) {
|
|
|
8307
8619
|
case "active":
|
|
8308
8620
|
return GREEN8("ACTIVE");
|
|
8309
8621
|
case "idle":
|
|
8310
|
-
return
|
|
8622
|
+
return AMBER9("IDLE");
|
|
8311
8623
|
case "stopped":
|
|
8312
8624
|
return GRAY7("STOPPED");
|
|
8313
8625
|
default:
|
|
@@ -8503,7 +8815,7 @@ function registerAgentCommand(program2) {
|
|
|
8503
8815
|
}
|
|
8504
8816
|
if (summary) {
|
|
8505
8817
|
console.log(BORDER12(" \u2502"));
|
|
8506
|
-
console.log(BORDER12(" \u2502") +
|
|
8818
|
+
console.log(BORDER12(" \u2502") + AMBER9(" Last Summary:"));
|
|
8507
8819
|
const summaryLines = summary.split("\n").filter((l) => l.trim()).slice(0, 4);
|
|
8508
8820
|
for (const line of summaryLines) {
|
|
8509
8821
|
console.log(
|
|
@@ -8540,7 +8852,7 @@ function registerAgentCommand(program2) {
|
|
|
8540
8852
|
const session = loadSession(name, cwd);
|
|
8541
8853
|
console.log("");
|
|
8542
8854
|
console.log(BORDER12(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
8543
|
-
console.log(BORDER12(" \u2502") +
|
|
8855
|
+
console.log(BORDER12(" \u2502") + AMBER9(` \u26A0\uFE0F WARNING: Reset @${name}`));
|
|
8544
8856
|
console.log(BORDER12(" \u2502"));
|
|
8545
8857
|
console.log(BORDER12(" \u2502") + RED7(" This will permanently delete:"));
|
|
8546
8858
|
console.log(BORDER12(" \u2502") + GRAY7(` \u2022 ${session?.messageCount || 0} messages of conversation history`));
|
|
@@ -8555,7 +8867,7 @@ function registerAgentCommand(program2) {
|
|
|
8555
8867
|
const { confirmed } = await inquirer2.prompt([{
|
|
8556
8868
|
type: "input",
|
|
8557
8869
|
name: "confirmed",
|
|
8558
|
-
message:
|
|
8870
|
+
message: AMBER9(` Type "@${name}" to confirm reset:`),
|
|
8559
8871
|
validate: (v) => v.trim() === `@${name}` || v.trim() === name ? true : `Type @${name} to confirm.`
|
|
8560
8872
|
}]);
|
|
8561
8873
|
if (confirmed.trim() !== `@${name}` && confirmed.trim() !== name) {
|
|
@@ -8583,7 +8895,7 @@ function registerAgentCommand(program2) {
|
|
|
8583
8895
|
}, 0);
|
|
8584
8896
|
console.log("");
|
|
8585
8897
|
console.log(BORDER12(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
8586
|
-
console.log(BORDER12(" \u2502") +
|
|
8898
|
+
console.log(BORDER12(" \u2502") + AMBER9(" \u26A0\uFE0F WARNING: Reset ALL Agents"));
|
|
8587
8899
|
console.log(BORDER12(" \u2502"));
|
|
8588
8900
|
console.log(BORDER12(" \u2502") + RED7(" This will permanently delete:"));
|
|
8589
8901
|
console.log(BORDER12(" \u2502") + GRAY7(` \u2022 ${registry.agents.length} agents`));
|
|
@@ -8597,7 +8909,7 @@ function registerAgentCommand(program2) {
|
|
|
8597
8909
|
const { confirmed } = await inquirer2.prompt([{
|
|
8598
8910
|
type: "confirm",
|
|
8599
8911
|
name: "confirmed",
|
|
8600
|
-
message:
|
|
8912
|
+
message: AMBER9(" Reset ALL agents?"),
|
|
8601
8913
|
default: false
|
|
8602
8914
|
}]);
|
|
8603
8915
|
if (!confirmed) {
|
|
@@ -8640,7 +8952,7 @@ function registerAgentCommand(program2) {
|
|
|
8640
8952
|
}
|
|
8641
8953
|
console.log("");
|
|
8642
8954
|
console.log(BORDER12(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
8643
|
-
console.log(BORDER12(" \u2551") +
|
|
8955
|
+
console.log(BORDER12(" \u2551") + AMBER9(" \u{1F4CB} Agent Summary"));
|
|
8644
8956
|
console.log(BORDER12(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
8645
8957
|
for (const agent of registry.agents) {
|
|
8646
8958
|
const summary = loadAgentSummary(agent.name, cwd);
|
|
@@ -10525,7 +10837,7 @@ import * as fs17 from "fs";
|
|
|
10525
10837
|
import * as path21 from "path";
|
|
10526
10838
|
import { diffLines as diffLines2 } from "diff";
|
|
10527
10839
|
var PURPLE4 = chalk29.hex("#AB47BC");
|
|
10528
|
-
var
|
|
10840
|
+
var AMBER10 = chalk29.hex("#FFAB00");
|
|
10529
10841
|
var GREEN9 = chalk29.hex("#66BB6A");
|
|
10530
10842
|
var RED8 = chalk29.hex("#EF5350");
|
|
10531
10843
|
var CYAN9 = chalk29.cyan;
|
|
@@ -10568,7 +10880,7 @@ function renderMissionHeader(mission, agentNames) {
|
|
|
10568
10880
|
console.log(BORDER13(" \u2551"));
|
|
10569
10881
|
console.log(BORDER13(" \u2551") + ` ${chips}`);
|
|
10570
10882
|
console.log(BORDER13(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
10571
|
-
console.log(BORDER13(" \u2551") +
|
|
10883
|
+
console.log(BORDER13(" \u2551") + AMBER10(" Live Commands:"));
|
|
10572
10884
|
console.log(BORDER13(" \u2551") + CYAN9(" /pause") + GRAY8(" \u2014 pause after active tasks"));
|
|
10573
10885
|
console.log(BORDER13(" \u2551") + CYAN9(" /resume") + GRAY8(" \u2014 resume from pause"));
|
|
10574
10886
|
console.log(BORDER13(" \u2551") + CYAN9(" /status") + GRAY8(" \u2014 full task map"));
|
|
@@ -10586,7 +10898,7 @@ function renderTaskMap(mission, agentNames) {
|
|
|
10586
10898
|
const summary = getMissionSummary(mission);
|
|
10587
10899
|
console.log("");
|
|
10588
10900
|
console.log(DIRECTOR_COLOR(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
10589
|
-
console.log(DIRECTOR_COLOR(" \u2551") +
|
|
10901
|
+
console.log(DIRECTOR_COLOR(" \u2551") + AMBER10(" \u{1F4CB} Task Map") + GRAY8(` \u2014 ${summary.total} tasks`));
|
|
10590
10902
|
console.log(DIRECTOR_COLOR(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
10591
10903
|
const running = mission.tasks.filter((t) => t.status === "running");
|
|
10592
10904
|
const pending = mission.tasks.filter((t) => t.status === "pending");
|
|
@@ -10702,7 +11014,7 @@ function renderExecutionEvent(event, agentNames) {
|
|
|
10702
11014
|
const toolName = event.data?.tool || "unknown";
|
|
10703
11015
|
const toolColors = {
|
|
10704
11016
|
createFile: GREEN9,
|
|
10705
|
-
modifyFile:
|
|
11017
|
+
modifyFile: AMBER10,
|
|
10706
11018
|
readFile: CYAN9,
|
|
10707
11019
|
writeOutput: BLUE4,
|
|
10708
11020
|
readAgentOutput: BLUE4,
|
|
@@ -10757,7 +11069,7 @@ async function renderPostMissionFeedback(mission, cwd) {
|
|
|
10757
11069
|
const os9 = await import("os");
|
|
10758
11070
|
console.log("");
|
|
10759
11071
|
console.log(DIRECTOR_COLOR(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
10760
|
-
console.log(DIRECTOR_COLOR(" \u2551") +
|
|
11072
|
+
console.log(DIRECTOR_COLOR(" \u2551") + AMBER10(" \u{1F4DD} Mission Feedback \u2014 Help train the agents"));
|
|
10761
11073
|
console.log(DIRECTOR_COLOR(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
10762
11074
|
console.log(DIRECTOR_COLOR(" \u2551") + GRAY8(" Your feedback improves future missions."));
|
|
10763
11075
|
console.log(DIRECTOR_COLOR(" \u2551") + GRAY8(" Press Enter to skip any task."));
|
|
@@ -10770,7 +11082,7 @@ async function renderPostMissionFeedback(mission, cwd) {
|
|
|
10770
11082
|
const chip = renderAgentChip(task.assignedTo, mission.tasks.map((t) => t.assignedTo), true);
|
|
10771
11083
|
console.log(` ${chip} ${GRAY8(task.instruction.slice(0, 60))}`);
|
|
10772
11084
|
const rating = await new Promise((resolve4) => {
|
|
10773
|
-
rl.question(
|
|
11085
|
+
rl.question(AMBER10(" Rate (\u{1F44D} good / \u{1F44E} bad / skip): "), resolve4);
|
|
10774
11086
|
});
|
|
10775
11087
|
const trimmed = rating.trim().toLowerCase();
|
|
10776
11088
|
if (trimmed === "" || trimmed === "skip") {
|
|
@@ -10862,7 +11174,7 @@ async function renderPostMissionCommitPrompt(mission, cwd) {
|
|
|
10862
11174
|
if (totalFiles === 0) return;
|
|
10863
11175
|
console.log("");
|
|
10864
11176
|
console.log(BORDER13(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
10865
|
-
console.log(BORDER13(" \u2551") +
|
|
11177
|
+
console.log(BORDER13(" \u2551") + AMBER10(" \u{1F4E6} Mission Changes \u2014 Ready to Commit"));
|
|
10866
11178
|
console.log(BORDER13(" \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
10867
11179
|
console.log("");
|
|
10868
11180
|
for (const filePath of allCreated) {
|
|
@@ -10927,7 +11239,7 @@ async function renderPostMissionCommitPrompt(mission, cwd) {
|
|
|
10927
11239
|
output: process.stdout
|
|
10928
11240
|
});
|
|
10929
11241
|
const answer = await new Promise((resolve4) => {
|
|
10930
|
-
rl.question(
|
|
11242
|
+
rl.question(AMBER10(" Commit these changes? (y/n): "), resolve4);
|
|
10931
11243
|
});
|
|
10932
11244
|
if (answer.trim().toLowerCase() !== "y" && answer.trim().toLowerCase() !== "yes") {
|
|
10933
11245
|
rl.close();
|
|
@@ -10937,7 +11249,7 @@ async function renderPostMissionCommitPrompt(mission, cwd) {
|
|
|
10937
11249
|
}
|
|
10938
11250
|
const defaultMessage = `feat(agents): ${mission.description.slice(0, 60)}`;
|
|
10939
11251
|
const messageAnswer = await new Promise((resolve4) => {
|
|
10940
|
-
rl.question(
|
|
11252
|
+
rl.question(AMBER10(` Commit message (Enter for default: "${defaultMessage.slice(0, 40)}..."): `), resolve4);
|
|
10941
11253
|
});
|
|
10942
11254
|
rl.close();
|
|
10943
11255
|
const commitMessage = messageAnswer.trim() || defaultMessage;
|
|
@@ -10965,7 +11277,7 @@ function handleRunCommand(input, state, mission, cwd) {
|
|
|
10965
11277
|
const trimmed = input.trim();
|
|
10966
11278
|
if (trimmed === "/pause") {
|
|
10967
11279
|
state.paused = true;
|
|
10968
|
-
return { handled: true, message:
|
|
11280
|
+
return { handled: true, message: AMBER10(" \u23F8\uFE0F Pausing after active tasks complete...") };
|
|
10969
11281
|
}
|
|
10970
11282
|
if (trimmed === "/resume") {
|
|
10971
11283
|
state.paused = false;
|
|
@@ -10989,7 +11301,7 @@ function handleRunCommand(input, state, mission, cwd) {
|
|
|
10989
11301
|
}
|
|
10990
11302
|
if (trimmed === "/view-targets") {
|
|
10991
11303
|
const lines = [""];
|
|
10992
|
-
lines.push(
|
|
11304
|
+
lines.push(AMBER10(" Satisfaction Targets:"));
|
|
10993
11305
|
lines.push(GRAY8(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10994
11306
|
for (const task of mission.tasks) {
|
|
10995
11307
|
const statusIcon2 = getTaskStatusIcon(task.status);
|
|
@@ -11046,7 +11358,7 @@ function getTaskStatusIcon(status) {
|
|
|
11046
11358
|
|
|
11047
11359
|
// src/commands/agent-run.ts
|
|
11048
11360
|
init_agent_tools();
|
|
11049
|
-
var
|
|
11361
|
+
var AMBER11 = chalk30.hex("#FFAB00");
|
|
11050
11362
|
var GREEN10 = chalk30.hex("#66BB6A");
|
|
11051
11363
|
var RED9 = chalk30.hex("#EF5350");
|
|
11052
11364
|
var CYAN10 = chalk30.cyan;
|
|
@@ -11065,7 +11377,7 @@ function registerAgentRunCommand(program2) {
|
|
|
11065
11377
|
const registry = loadRegistry(cwd);
|
|
11066
11378
|
if (registry.agents.length === 0) {
|
|
11067
11379
|
console.log("");
|
|
11068
|
-
console.log(
|
|
11380
|
+
console.log(AMBER11(" \u26A0\uFE0F No agents found."));
|
|
11069
11381
|
console.log(GRAY9(' Spawn agents first: bob agent spawn <name> "<task>"'));
|
|
11070
11382
|
console.log("");
|
|
11071
11383
|
return;
|
|
@@ -11075,7 +11387,7 @@ function registerAgentRunCommand(program2) {
|
|
|
11075
11387
|
);
|
|
11076
11388
|
if (agents.length === 0) {
|
|
11077
11389
|
console.log("");
|
|
11078
|
-
console.log(
|
|
11390
|
+
console.log(AMBER11(" \u26A0\uFE0F No active agents found."));
|
|
11079
11391
|
console.log("");
|
|
11080
11392
|
return;
|
|
11081
11393
|
}
|
|
@@ -11083,7 +11395,7 @@ function registerAgentRunCommand(program2) {
|
|
|
11083
11395
|
const activeMissionId = getActiveMissionId(cwd);
|
|
11084
11396
|
if (!activeMissionId) {
|
|
11085
11397
|
console.log("");
|
|
11086
|
-
console.log(
|
|
11398
|
+
console.log(AMBER11(" \u26A0\uFE0F No active mission to resume."));
|
|
11087
11399
|
console.log("");
|
|
11088
11400
|
return;
|
|
11089
11401
|
}
|
|
@@ -11095,7 +11407,7 @@ function registerAgentRunCommand(program2) {
|
|
|
11095
11407
|
return;
|
|
11096
11408
|
}
|
|
11097
11409
|
console.log("");
|
|
11098
|
-
console.log(
|
|
11410
|
+
console.log(AMBER11(` \u{1F504} Resuming mission: ${existingMission.description.slice(0, 50)}...`));
|
|
11099
11411
|
await executeMission(existingMission, agents, cwd, config.localEndpoint, options);
|
|
11100
11412
|
return;
|
|
11101
11413
|
}
|
|
@@ -11106,7 +11418,7 @@ function registerAgentRunCommand(program2) {
|
|
|
11106
11418
|
output: process.stdout
|
|
11107
11419
|
});
|
|
11108
11420
|
missionDescription = await new Promise((resolve4) => {
|
|
11109
|
-
rl.question(
|
|
11421
|
+
rl.question(AMBER11(" \u{1F3AC} What is the mission? > "), resolve4);
|
|
11110
11422
|
});
|
|
11111
11423
|
rl.close();
|
|
11112
11424
|
if (!missionDescription.trim()) {
|
|
@@ -11118,7 +11430,7 @@ function registerAgentRunCommand(program2) {
|
|
|
11118
11430
|
clearAllPendingCommits(cwd);
|
|
11119
11431
|
console.log("");
|
|
11120
11432
|
const planSpinner = ora13({
|
|
11121
|
-
text:
|
|
11433
|
+
text: AMBER11(" \u{1F3AC} DirectorBob is analyzing your team and building the task map..."),
|
|
11122
11434
|
spinner: "dots"
|
|
11123
11435
|
}).start();
|
|
11124
11436
|
let taskDefs;
|
|
@@ -11175,7 +11487,7 @@ function registerAgentRunCommand(program2) {
|
|
|
11175
11487
|
console.log("");
|
|
11176
11488
|
return;
|
|
11177
11489
|
}
|
|
11178
|
-
console.log(
|
|
11490
|
+
console.log(AMBER11(" Starting in 3 seconds... (Ctrl+C to abort)"));
|
|
11179
11491
|
await new Promise((r) => setTimeout(r, 3e3));
|
|
11180
11492
|
await executeMission(mission, agents, cwd, config.localEndpoint, options);
|
|
11181
11493
|
});
|
|
@@ -11254,7 +11566,7 @@ async function executeMission(mission, agents, cwd, localEndpoint, options) {
|
|
|
11254
11566
|
console.log("");
|
|
11255
11567
|
} else if (result.surfacedToUser) {
|
|
11256
11568
|
console.log("");
|
|
11257
|
-
console.log(
|
|
11569
|
+
console.log(AMBER11(" \u26A0\uFE0F Mission needs your attention."));
|
|
11258
11570
|
console.log(RED9(` Reason: ${result.surfaceReason}`));
|
|
11259
11571
|
console.log("");
|
|
11260
11572
|
console.log(GRAY9(" Options:"));
|
|
@@ -11278,7 +11590,7 @@ import * as fs18 from "fs";
|
|
|
11278
11590
|
import * as path22 from "path";
|
|
11279
11591
|
import * as os8 from "os";
|
|
11280
11592
|
var PURPLE5 = chalk31.hex("#AB47BC");
|
|
11281
|
-
var
|
|
11593
|
+
var AMBER12 = chalk31.hex("#FFAB00");
|
|
11282
11594
|
var GREEN11 = chalk31.hex("#66BB6A");
|
|
11283
11595
|
var CYAN11 = chalk31.hex("#26C6DA");
|
|
11284
11596
|
var RED10 = chalk31.hex("#EF5350");
|
|
@@ -11312,7 +11624,7 @@ function clearSessionFile() {
|
|
|
11312
11624
|
if (fs18.existsSync(filePath)) fs18.unlinkSync(filePath);
|
|
11313
11625
|
}
|
|
11314
11626
|
function renderHUD(sat, target, stag, stagTarget, div, divTarget, grading) {
|
|
11315
|
-
const satBar = sat >= target ? GREEN11(`${sat}%`) : sat >= target * 0.7 ?
|
|
11627
|
+
const satBar = sat >= target ? GREEN11(`${sat}%`) : sat >= target * 0.7 ? AMBER12(`${sat}%`) : RED10(`${sat}%`);
|
|
11316
11628
|
console.log("");
|
|
11317
11629
|
console.log(BORDER14(" \u2500\u2500\u2500 MISSION CONTROL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
11318
11630
|
console.log(
|
|
@@ -11395,7 +11707,7 @@ async function handleSlashCommand(input, config, conversationId) {
|
|
|
11395
11707
|
const response = await callCloudFunction("getCLIConversationMessages", { conversationId, since: null });
|
|
11396
11708
|
const state = response?.state || {};
|
|
11397
11709
|
console.log("");
|
|
11398
|
-
console.log(
|
|
11710
|
+
console.log(AMBER12(" \u2500\u2500\u2500 Current Parameters \u2500\u2500\u2500"));
|
|
11399
11711
|
console.log(GRAY10(` Target Satisfaction : ${state.targetSatisfaction ?? "N/A"}`));
|
|
11400
11712
|
console.log(GRAY10(` Grading Standard : ${state.gradingStandard ?? "N/A"}`));
|
|
11401
11713
|
console.log(GRAY10(` Current Satisfaction: ${state.currentSatisfaction ?? "N/A"}`));
|
|
@@ -11478,13 +11790,13 @@ async function runPlatformSimulation(config, conversationId, mission, params) {
|
|
|
11478
11790
|
console.log(GRAY10(" Messages will stream below as Bob and UserBob interact."));
|
|
11479
11791
|
console.log(GRAY10(" You can type commands at any time:"));
|
|
11480
11792
|
console.log("");
|
|
11481
|
-
console.log(
|
|
11482
|
-
console.log(
|
|
11483
|
-
console.log(
|
|
11484
|
-
console.log(
|
|
11485
|
-
console.log(
|
|
11486
|
-
console.log(
|
|
11487
|
-
console.log(
|
|
11793
|
+
console.log(AMBER12(" /abort") + GRAY10(" \u2014 Stop the simulation immediately"));
|
|
11794
|
+
console.log(AMBER12(" /set target 90") + GRAY10(" \u2014 Update satisfaction target"));
|
|
11795
|
+
console.log(AMBER12(" /set grading 70") + GRAY10(" \u2014 Update Teacher's Curve"));
|
|
11796
|
+
console.log(AMBER12(" /set stag 5") + GRAY10(" \u2014 Update stalemate threshold"));
|
|
11797
|
+
console.log(AMBER12(" /set div 3") + GRAY10(" \u2014 Update divergence threshold"));
|
|
11798
|
+
console.log(AMBER12(' /inject "note"') + GRAY10(" \u2014 Inject a director's note mid-session"));
|
|
11799
|
+
console.log(AMBER12(" /status") + GRAY10(" \u2014 Show current simulation parameters"));
|
|
11488
11800
|
console.log("");
|
|
11489
11801
|
console.log(BORDER14(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
11490
11802
|
console.log("");
|
|
@@ -11495,7 +11807,7 @@ async function runPlatformSimulation(config, conversationId, mission, params) {
|
|
|
11495
11807
|
if (!running) return;
|
|
11496
11808
|
running = false;
|
|
11497
11809
|
console.log("\n");
|
|
11498
|
-
console.log(
|
|
11810
|
+
console.log(AMBER12(" \u{1F6D1} Aborting simulation..."));
|
|
11499
11811
|
try {
|
|
11500
11812
|
await callHTTPFunction("userSimManagerService", {
|
|
11501
11813
|
action: "abortMission",
|
|
@@ -11516,7 +11828,7 @@ async function runPlatformSimulation(config, conversationId, mission, params) {
|
|
|
11516
11828
|
if (!trimmed) return;
|
|
11517
11829
|
if (trimmed === "/abort" || trimmed === "abort") {
|
|
11518
11830
|
running = false;
|
|
11519
|
-
console.log(
|
|
11831
|
+
console.log(AMBER12(" \u{1F6D1} Aborting simulation..."));
|
|
11520
11832
|
try {
|
|
11521
11833
|
await callHTTPFunction("userSimManagerService", {
|
|
11522
11834
|
action: "abortMission",
|
|
@@ -11563,7 +11875,7 @@ async function runPlatformSimulation(config, conversationId, mission, params) {
|
|
|
11563
11875
|
renderHUD(hudState.sat, hudState.target, hudState.stag, hudState.stagTarget, hudState.div, hudState.divTarget, hudState.grading);
|
|
11564
11876
|
}
|
|
11565
11877
|
console.log("");
|
|
11566
|
-
console.log(
|
|
11878
|
+
console.log(AMBER12(` \u{1F3C1} Simulation ended: ${state.simulationStatus || "INACTIVE"}`));
|
|
11567
11879
|
console.log("");
|
|
11568
11880
|
running = false;
|
|
11569
11881
|
break;
|
|
@@ -11591,7 +11903,7 @@ async function runLocalSimulation(config, dnaString, mission, params) {
|
|
|
11591
11903
|
running = false;
|
|
11592
11904
|
writeSessionFile({ active: false });
|
|
11593
11905
|
clearSessionFile();
|
|
11594
|
-
console.log("\n" +
|
|
11906
|
+
console.log("\n" + AMBER12(" \u{1F6D1} Simulation stopped."));
|
|
11595
11907
|
process.exit(0);
|
|
11596
11908
|
};
|
|
11597
11909
|
process.on("SIGINT", sigintHandler);
|
|
@@ -11603,7 +11915,7 @@ async function runLocalSimulation(config, dnaString, mission, params) {
|
|
|
11603
11915
|
running = false;
|
|
11604
11916
|
writeSessionFile({ active: false });
|
|
11605
11917
|
clearSessionFile();
|
|
11606
|
-
console.log(
|
|
11918
|
+
console.log(AMBER12(" \u{1F6D1} Simulation stopped."));
|
|
11607
11919
|
rl.close();
|
|
11608
11920
|
process.exit(0);
|
|
11609
11921
|
}
|
|
@@ -11620,7 +11932,7 @@ async function runLocalSimulation(config, dnaString, mission, params) {
|
|
|
11620
11932
|
}
|
|
11621
11933
|
if (t === "/status") {
|
|
11622
11934
|
console.log("");
|
|
11623
|
-
console.log(
|
|
11935
|
+
console.log(AMBER12(" \u2500\u2500\u2500 Local Sim Parameters \u2500\u2500\u2500"));
|
|
11624
11936
|
console.log(GRAY10(` Target: ${params.target} \u2502 Grading: ${params.grading} \u2502 Stag Limit: ${params.stag} \u2502 Div Limit: ${params.div}`));
|
|
11625
11937
|
console.log(GRAY10(` Current SAT: ${sat} \u2502 Turns: ${turns} \u2502 Stag: ${stalemateCurrent} \u2502 Div: ${divergenceCurrent}`));
|
|
11626
11938
|
console.log("");
|
|
@@ -11643,12 +11955,12 @@ After each Bob response, evaluate it 0-100 on mission alignment. Reply with your
|
|
|
11643
11955
|
console.log(BORDER14(" \u2500\u2500\u2500 LIVE LOCAL SIMULATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
11644
11956
|
console.log(GRAY10(" Bob and UserBob will converse autonomously below."));
|
|
11645
11957
|
console.log(GRAY10(" Commands:"));
|
|
11646
|
-
console.log(
|
|
11647
|
-
console.log(
|
|
11648
|
-
console.log(
|
|
11649
|
-
console.log(
|
|
11650
|
-
console.log(
|
|
11651
|
-
console.log(
|
|
11958
|
+
console.log(AMBER12(" /abort") + GRAY10(" \u2014 Stop the simulation"));
|
|
11959
|
+
console.log(AMBER12(" /set target 90") + GRAY10(" \u2014 Update satisfaction target"));
|
|
11960
|
+
console.log(AMBER12(" /set grading 70") + GRAY10(" \u2014 Update Teacher's Curve"));
|
|
11961
|
+
console.log(AMBER12(" /set stag 5") + GRAY10(" \u2014 Update stalemate threshold"));
|
|
11962
|
+
console.log(AMBER12(" /set div 3") + GRAY10(" \u2014 Update divergence threshold"));
|
|
11963
|
+
console.log(AMBER12(" /status") + GRAY10(" \u2014 Show current parameters"));
|
|
11652
11964
|
console.log(BORDER14(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
11653
11965
|
console.log("");
|
|
11654
11966
|
const kickstart = `Mission received: "${mission}". Bob, what's your first move?`;
|
|
@@ -11690,7 +12002,7 @@ After each Bob response, evaluate it 0-100 on mission alignment. Reply with your
|
|
|
11690
12002
|
if (params.stag > 0 && stalemateCurrent >= params.stag) {
|
|
11691
12003
|
console.log(" " + auditChips.join(" "));
|
|
11692
12004
|
renderHUD(sat, params.target, stalemateCurrent, params.stag, divergenceCurrent, params.div, params.grading);
|
|
11693
|
-
console.log(
|
|
12005
|
+
console.log(AMBER12(` \u{1F3C1} Stalemate threshold reached (${stalemateCurrent}/${params.stag}). Simulation ended.`));
|
|
11694
12006
|
running = false;
|
|
11695
12007
|
break;
|
|
11696
12008
|
}
|
|
@@ -11700,7 +12012,7 @@ After each Bob response, evaluate it 0-100 on mission alignment. Reply with your
|
|
|
11700
12012
|
if (params.div > 0 && divergenceCurrent >= params.div) {
|
|
11701
12013
|
console.log(" " + auditChips.join(" "));
|
|
11702
12014
|
renderHUD(sat, params.target, stalemateCurrent, params.stag, divergenceCurrent, params.div, params.grading);
|
|
11703
|
-
console.log(
|
|
12015
|
+
console.log(AMBER12(` \u{1F3C1} Divergence threshold reached (${divergenceCurrent}/${params.div}). Simulation ended.`));
|
|
11704
12016
|
running = false;
|
|
11705
12017
|
break;
|
|
11706
12018
|
}
|
|
@@ -11754,11 +12066,11 @@ function registerUserBobCommand(program2) {
|
|
|
11754
12066
|
if (dna) {
|
|
11755
12067
|
console.log(GREEN11(" \u2705 Behavioral DNA loaded."));
|
|
11756
12068
|
} else {
|
|
11757
|
-
console.log(
|
|
12069
|
+
console.log(AMBER12(" \u26A0\uFE0F No behavioral profile found."));
|
|
11758
12070
|
console.log(GRAY10(" UserBob performs significantly better with your DNA loaded."));
|
|
11759
12071
|
console.log("");
|
|
11760
12072
|
const rl = readline11.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
11761
|
-
const answer = await new Promise((resolve4) => rl.question(
|
|
12073
|
+
const answer = await new Promise((resolve4) => rl.question(AMBER12(" Run `bob profile --today` now? (y/n): "), resolve4));
|
|
11762
12074
|
rl.close();
|
|
11763
12075
|
if (answer.trim().toLowerCase() === "y") {
|
|
11764
12076
|
console.log("");
|
|
@@ -11777,7 +12089,7 @@ function registerUserBobCommand(program2) {
|
|
|
11777
12089
|
let mission = missionArgs.length > 0 ? missionArgs.join(" ") : "";
|
|
11778
12090
|
if (!mission && !options.resume) {
|
|
11779
12091
|
const mrl = readline11.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
11780
|
-
mission = await new Promise((resolve4) => mrl.question(
|
|
12092
|
+
mission = await new Promise((resolve4) => mrl.question(AMBER12(" What's the mission? > "), resolve4));
|
|
11781
12093
|
mrl.close();
|
|
11782
12094
|
if (!mission.trim()) {
|
|
11783
12095
|
console.log(RED10(" \u274C Mission cannot be empty. Exiting."));
|
|
@@ -11795,7 +12107,7 @@ function registerUserBobCommand(program2) {
|
|
|
11795
12107
|
process.exit(1);
|
|
11796
12108
|
}
|
|
11797
12109
|
if (options.resume) {
|
|
11798
|
-
console.log(
|
|
12110
|
+
console.log(AMBER12(" \u{1F504} Resuming simulation (no new mission note)..."));
|
|
11799
12111
|
await callHTTPFunction("userSimManagerService", {
|
|
11800
12112
|
action: "resumeMission",
|
|
11801
12113
|
conversationId,
|