devwing 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +288 -228
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1631,230 +1631,6 @@ async function promptCommand(prompt, options) {
|
|
|
1631
1631
|
process.exit(1);
|
|
1632
1632
|
}
|
|
1633
1633
|
}
|
|
1634
|
-
var ChatSession = class {
|
|
1635
|
-
conversationHistory = [];
|
|
1636
|
-
sessionContext = null;
|
|
1637
|
-
sessionId = null;
|
|
1638
|
-
addMessage(role, content) {
|
|
1639
|
-
this.conversationHistory.push({ role, content });
|
|
1640
|
-
}
|
|
1641
|
-
getHistory() {
|
|
1642
|
-
return this.conversationHistory;
|
|
1643
|
-
}
|
|
1644
|
-
setContext(context) {
|
|
1645
|
-
this.sessionContext = context;
|
|
1646
|
-
}
|
|
1647
|
-
getContext() {
|
|
1648
|
-
return this.sessionContext;
|
|
1649
|
-
}
|
|
1650
|
-
setSessionId(id) {
|
|
1651
|
-
this.sessionId = id;
|
|
1652
|
-
}
|
|
1653
|
-
getSessionId() {
|
|
1654
|
-
return this.sessionId;
|
|
1655
|
-
}
|
|
1656
|
-
clear() {
|
|
1657
|
-
this.conversationHistory = [];
|
|
1658
|
-
this.sessionId = null;
|
|
1659
|
-
}
|
|
1660
|
-
getConversationSummary() {
|
|
1661
|
-
return this.conversationHistory.map((msg) => `${msg.role === "user" ? "You" : "DevWing"}: ${msg.content.substring(0, 100)}...`).join("\n");
|
|
1662
|
-
}
|
|
1663
|
-
};
|
|
1664
|
-
function handleSpecialCommand(command, session) {
|
|
1665
|
-
const cmd = command.toLowerCase();
|
|
1666
|
-
if (cmd === "/help") {
|
|
1667
|
-
logger.box([
|
|
1668
|
-
chalk3.bold("DevWing Chat Commands:"),
|
|
1669
|
-
"",
|
|
1670
|
-
chalk3.cyan("/help") + " - Show this help message",
|
|
1671
|
-
chalk3.cyan("/exit, /quit") + " - Exit chat mode",
|
|
1672
|
-
chalk3.cyan("/clear") + " - Clear conversation history",
|
|
1673
|
-
chalk3.cyan("/context") + " - Show current context",
|
|
1674
|
-
chalk3.cyan("/history") + " - Show conversation history",
|
|
1675
|
-
chalk3.cyan("/memory save") + " - Save note to project memory",
|
|
1676
|
-
"",
|
|
1677
|
-
"Just type your message to chat with DevWing!"
|
|
1678
|
-
].join("\n"), { title: "Chat Commands", color: "blue" });
|
|
1679
|
-
return true;
|
|
1680
|
-
}
|
|
1681
|
-
if (cmd === "/exit" || cmd === "/quit") {
|
|
1682
|
-
logger.info("Exiting chat mode...");
|
|
1683
|
-
return false;
|
|
1684
|
-
}
|
|
1685
|
-
if (cmd === "/clear") {
|
|
1686
|
-
session.clear();
|
|
1687
|
-
console.clear();
|
|
1688
|
-
logger.success("Conversation cleared!");
|
|
1689
|
-
printWelcomeBanner();
|
|
1690
|
-
return true;
|
|
1691
|
-
}
|
|
1692
|
-
if (cmd === "/context") {
|
|
1693
|
-
const context = session.getContext();
|
|
1694
|
-
if (!context) {
|
|
1695
|
-
logger.warn("No context loaded yet. Send a message to load context.");
|
|
1696
|
-
return true;
|
|
1697
|
-
}
|
|
1698
|
-
logger.box([
|
|
1699
|
-
chalk3.bold("Current Context:"),
|
|
1700
|
-
"",
|
|
1701
|
-
`Working Directory: ${chalk3.cyan(context.cwd)}`,
|
|
1702
|
-
`Shell: ${context.shell}`,
|
|
1703
|
-
`OS: ${context.os}`,
|
|
1704
|
-
`Files: ${context.files.length}`,
|
|
1705
|
-
context.git_branch ? `Git Branch: ${context.git_branch}` : "",
|
|
1706
|
-
"",
|
|
1707
|
-
"Files included:",
|
|
1708
|
-
...context.files.slice(0, 10).map((f) => ` \u2022 ${f.path}`),
|
|
1709
|
-
context.files.length > 10 ? ` ... and ${context.files.length - 10} more` : ""
|
|
1710
|
-
].filter(Boolean).join("\n"), { title: "Context Info", color: "cyan" });
|
|
1711
|
-
return true;
|
|
1712
|
-
}
|
|
1713
|
-
if (cmd === "/history") {
|
|
1714
|
-
const history = session.getHistory();
|
|
1715
|
-
if (history.length === 0) {
|
|
1716
|
-
logger.info("No conversation history yet.");
|
|
1717
|
-
return true;
|
|
1718
|
-
}
|
|
1719
|
-
logger.box([
|
|
1720
|
-
chalk3.bold("Conversation History:"),
|
|
1721
|
-
"",
|
|
1722
|
-
session.getConversationSummary()
|
|
1723
|
-
].join("\n"), { title: "History", color: "magenta" });
|
|
1724
|
-
return true;
|
|
1725
|
-
}
|
|
1726
|
-
return true;
|
|
1727
|
-
}
|
|
1728
|
-
function printWelcomeBanner() {
|
|
1729
|
-
logger.box([
|
|
1730
|
-
chalk3.bold.cyan("DevWing AI - Interactive Chat Mode"),
|
|
1731
|
-
"",
|
|
1732
|
-
"Chat with AI about your codebase. Type your message and press Enter.",
|
|
1733
|
-
"",
|
|
1734
|
-
chalk3.dim("Type /help for commands \u2022 /exit to quit")
|
|
1735
|
-
].join("\n"), { title: "\u{1F680} Welcome", color: "cyan" });
|
|
1736
|
-
}
|
|
1737
|
-
async function chatCommand(options) {
|
|
1738
|
-
try {
|
|
1739
|
-
const apiKey = await configManager.getApiKey();
|
|
1740
|
-
if (!apiKey) {
|
|
1741
|
-
logger.error('Not authenticated. Run "devwing login" first.');
|
|
1742
|
-
process.exit(1);
|
|
1743
|
-
}
|
|
1744
|
-
const session = new ChatSession();
|
|
1745
|
-
console.clear();
|
|
1746
|
-
printWelcomeBanner();
|
|
1747
|
-
logger.newline();
|
|
1748
|
-
const rl = readline.createInterface({
|
|
1749
|
-
input: process.stdin,
|
|
1750
|
-
output: process.stdout,
|
|
1751
|
-
prompt: chalk3.bold.green("You: ")
|
|
1752
|
-
});
|
|
1753
|
-
rl.on("SIGINT", () => {
|
|
1754
|
-
logger.newline();
|
|
1755
|
-
logger.info("Exiting chat mode...");
|
|
1756
|
-
rl.close();
|
|
1757
|
-
process.exit(0);
|
|
1758
|
-
});
|
|
1759
|
-
logger.startSpinner("Loading codebase context...");
|
|
1760
|
-
const collector = new ContextCollector(process.cwd());
|
|
1761
|
-
const initialContext = await collector.collect("");
|
|
1762
|
-
session.setContext(initialContext);
|
|
1763
|
-
logger.succeedSpinner("Context loaded!");
|
|
1764
|
-
logger.newline();
|
|
1765
|
-
rl.prompt();
|
|
1766
|
-
rl.on("line", async (input) => {
|
|
1767
|
-
const userMessage = input.trim();
|
|
1768
|
-
if (!userMessage) {
|
|
1769
|
-
rl.prompt();
|
|
1770
|
-
return;
|
|
1771
|
-
}
|
|
1772
|
-
if (userMessage.startsWith("/")) {
|
|
1773
|
-
const shouldContinue = handleSpecialCommand(userMessage, session);
|
|
1774
|
-
if (!shouldContinue) {
|
|
1775
|
-
rl.close();
|
|
1776
|
-
return;
|
|
1777
|
-
}
|
|
1778
|
-
logger.newline();
|
|
1779
|
-
rl.prompt();
|
|
1780
|
-
return;
|
|
1781
|
-
}
|
|
1782
|
-
session.addMessage("user", userMessage);
|
|
1783
|
-
logger.newline();
|
|
1784
|
-
logger.info(chalk3.dim("DevWing is thinking..."));
|
|
1785
|
-
logger.newline();
|
|
1786
|
-
try {
|
|
1787
|
-
const request = {
|
|
1788
|
-
prompt: buildPromptWithHistory(session),
|
|
1789
|
-
mode: options.mode,
|
|
1790
|
-
model: options.model,
|
|
1791
|
-
project_id: options.project || configManager.getProjectId(),
|
|
1792
|
-
context: session.getContext(),
|
|
1793
|
-
stream: true,
|
|
1794
|
-
max_tokens: 4096
|
|
1795
|
-
};
|
|
1796
|
-
let assistantResponse = "";
|
|
1797
|
-
streamingRenderer.reset();
|
|
1798
|
-
streamingRenderer.clearPendingTools();
|
|
1799
|
-
for await (const message of apiClient.streamCompletion(request)) {
|
|
1800
|
-
await streamingRenderer.processMessage(message);
|
|
1801
|
-
if (message.type === "token" && message.content) {
|
|
1802
|
-
assistantResponse += message.content;
|
|
1803
|
-
}
|
|
1804
|
-
if (message.session_id) {
|
|
1805
|
-
session.setSessionId(message.session_id);
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
if (assistantResponse) {
|
|
1809
|
-
session.addMessage("assistant", assistantResponse);
|
|
1810
|
-
}
|
|
1811
|
-
const pendingTools = streamingRenderer.getPendingToolCalls();
|
|
1812
|
-
if (pendingTools.length > 0) {
|
|
1813
|
-
logger.newline();
|
|
1814
|
-
logger.info("Executing tools...");
|
|
1815
|
-
const toolResults = await streamingRenderer.executePendingTools();
|
|
1816
|
-
if (session.getSessionId()) {
|
|
1817
|
-
for await (const message of apiClient.continueCompletion(session.getSessionId(), toolResults)) {
|
|
1818
|
-
await streamingRenderer.processMessage(message);
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
logger.newline();
|
|
1823
|
-
logger.newline();
|
|
1824
|
-
} catch (error) {
|
|
1825
|
-
logger.newline();
|
|
1826
|
-
logger.error("Error:", error.message || error);
|
|
1827
|
-
logger.newline();
|
|
1828
|
-
}
|
|
1829
|
-
rl.prompt();
|
|
1830
|
-
});
|
|
1831
|
-
rl.on("close", () => {
|
|
1832
|
-
logger.newline();
|
|
1833
|
-
logger.success("Chat session ended. Goodbye!");
|
|
1834
|
-
process.exit(0);
|
|
1835
|
-
});
|
|
1836
|
-
} catch (error) {
|
|
1837
|
-
logger.error("Chat command failed", error);
|
|
1838
|
-
process.exit(1);
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
function buildPromptWithHistory(session) {
|
|
1842
|
-
const history = session.getHistory();
|
|
1843
|
-
if (history.length === 0) {
|
|
1844
|
-
return "";
|
|
1845
|
-
}
|
|
1846
|
-
const lastUserMessage = history[history.length - 1];
|
|
1847
|
-
if (history.length === 1) {
|
|
1848
|
-
return lastUserMessage.content;
|
|
1849
|
-
}
|
|
1850
|
-
const recentHistory = history.slice(-10);
|
|
1851
|
-
const historyContext = recentHistory.slice(0, -1).map((msg) => `${msg.role === "user" ? "User" : "Assistant"}: ${msg.content}`).join("\n\n");
|
|
1852
|
-
return `Previous conversation:
|
|
1853
|
-
${historyContext}
|
|
1854
|
-
|
|
1855
|
-
Current question:
|
|
1856
|
-
${lastUserMessage.content}`;
|
|
1857
|
-
}
|
|
1858
1634
|
async function scanCommand(options) {
|
|
1859
1635
|
logger.info("Running security vulnerability scan...");
|
|
1860
1636
|
logger.newline();
|
|
@@ -2069,6 +1845,290 @@ async function configCommand(action, key, value) {
|
|
|
2069
1845
|
process.exit(1);
|
|
2070
1846
|
}
|
|
2071
1847
|
}
|
|
1848
|
+
|
|
1849
|
+
// src/commands/chat.ts
|
|
1850
|
+
var ChatSession = class {
|
|
1851
|
+
conversationHistory = [];
|
|
1852
|
+
sessionContext = null;
|
|
1853
|
+
sessionId = null;
|
|
1854
|
+
addMessage(role, content) {
|
|
1855
|
+
this.conversationHistory.push({ role, content });
|
|
1856
|
+
}
|
|
1857
|
+
getHistory() {
|
|
1858
|
+
return this.conversationHistory;
|
|
1859
|
+
}
|
|
1860
|
+
setContext(context) {
|
|
1861
|
+
this.sessionContext = context;
|
|
1862
|
+
}
|
|
1863
|
+
getContext() {
|
|
1864
|
+
return this.sessionContext;
|
|
1865
|
+
}
|
|
1866
|
+
setSessionId(id) {
|
|
1867
|
+
this.sessionId = id;
|
|
1868
|
+
}
|
|
1869
|
+
getSessionId() {
|
|
1870
|
+
return this.sessionId;
|
|
1871
|
+
}
|
|
1872
|
+
clear() {
|
|
1873
|
+
this.conversationHistory = [];
|
|
1874
|
+
this.sessionId = null;
|
|
1875
|
+
}
|
|
1876
|
+
getConversationSummary() {
|
|
1877
|
+
return this.conversationHistory.map((msg) => `${msg.role === "user" ? "You" : "DevWing"}: ${msg.content.substring(0, 100)}...`).join("\n");
|
|
1878
|
+
}
|
|
1879
|
+
};
|
|
1880
|
+
async function handleSpecialCommand(command, session, options) {
|
|
1881
|
+
const cmd = command.toLowerCase().trim();
|
|
1882
|
+
const parts = command.split(" ");
|
|
1883
|
+
const mainCmd = parts[0].toLowerCase();
|
|
1884
|
+
if (cmd === "/help") {
|
|
1885
|
+
logger.box([
|
|
1886
|
+
chalk3.bold("DevWing Chat Commands:"),
|
|
1887
|
+
"",
|
|
1888
|
+
chalk3.bold.yellow("Navigation & Session:"),
|
|
1889
|
+
chalk3.cyan("/help") + " - Show this help message",
|
|
1890
|
+
chalk3.cyan("/exit, /quit") + " - Exit chat mode",
|
|
1891
|
+
chalk3.cyan("/clear") + " - Clear conversation history",
|
|
1892
|
+
chalk3.cyan("/context") + " - Show current context",
|
|
1893
|
+
chalk3.cyan("/history") + " - Show conversation history",
|
|
1894
|
+
"",
|
|
1895
|
+
chalk3.bold.yellow("Specialized Commands:"),
|
|
1896
|
+
chalk3.cyan("/scan") + " - Run security vulnerability scan",
|
|
1897
|
+
chalk3.cyan("/review") + " - Perform code review",
|
|
1898
|
+
chalk3.cyan("/explain <target>") + " - Explain code, file, or concept",
|
|
1899
|
+
"",
|
|
1900
|
+
chalk3.bold.yellow("Project Memory:"),
|
|
1901
|
+
chalk3.cyan("/memory save <content>") + " - Save note to project memory",
|
|
1902
|
+
chalk3.cyan("/memory show") + " - Show all project memories",
|
|
1903
|
+
chalk3.cyan("/memory clear") + " - Clear all project memories",
|
|
1904
|
+
"",
|
|
1905
|
+
chalk3.dim("Just type your message to chat with DevWing!")
|
|
1906
|
+
].join("\n"), { title: "Chat Commands", color: "blue" });
|
|
1907
|
+
return true;
|
|
1908
|
+
}
|
|
1909
|
+
if (cmd === "/exit" || cmd === "/quit") {
|
|
1910
|
+
logger.info("Exiting chat mode...");
|
|
1911
|
+
return false;
|
|
1912
|
+
}
|
|
1913
|
+
if (cmd === "/clear") {
|
|
1914
|
+
session.clear();
|
|
1915
|
+
console.clear();
|
|
1916
|
+
logger.success("Conversation cleared!");
|
|
1917
|
+
printWelcomeBanner();
|
|
1918
|
+
return true;
|
|
1919
|
+
}
|
|
1920
|
+
if (cmd === "/context") {
|
|
1921
|
+
const context = session.getContext();
|
|
1922
|
+
if (!context) {
|
|
1923
|
+
logger.warn("No context loaded yet. Send a message to load context.");
|
|
1924
|
+
return true;
|
|
1925
|
+
}
|
|
1926
|
+
logger.box([
|
|
1927
|
+
chalk3.bold("Current Context:"),
|
|
1928
|
+
"",
|
|
1929
|
+
`Working Directory: ${chalk3.cyan(context.cwd)}`,
|
|
1930
|
+
`Shell: ${context.shell}`,
|
|
1931
|
+
`OS: ${context.os}`,
|
|
1932
|
+
`Files: ${context.files.length}`,
|
|
1933
|
+
context.git_branch ? `Git Branch: ${context.git_branch}` : "",
|
|
1934
|
+
"",
|
|
1935
|
+
"Files included:",
|
|
1936
|
+
...context.files.slice(0, 10).map((f) => ` \u2022 ${f.path}`),
|
|
1937
|
+
context.files.length > 10 ? ` ... and ${context.files.length - 10} more` : ""
|
|
1938
|
+
].filter(Boolean).join("\n"), { title: "Context Info", color: "cyan" });
|
|
1939
|
+
return true;
|
|
1940
|
+
}
|
|
1941
|
+
if (cmd === "/history") {
|
|
1942
|
+
const history = session.getHistory();
|
|
1943
|
+
if (history.length === 0) {
|
|
1944
|
+
logger.info("No conversation history yet.");
|
|
1945
|
+
return true;
|
|
1946
|
+
}
|
|
1947
|
+
logger.box([
|
|
1948
|
+
chalk3.bold("Conversation History:"),
|
|
1949
|
+
"",
|
|
1950
|
+
session.getConversationSummary()
|
|
1951
|
+
].join("\n"), { title: "History", color: "magenta" });
|
|
1952
|
+
return true;
|
|
1953
|
+
}
|
|
1954
|
+
if (cmd === "/scan") {
|
|
1955
|
+
logger.newline();
|
|
1956
|
+
await scanCommand(options);
|
|
1957
|
+
return true;
|
|
1958
|
+
}
|
|
1959
|
+
if (cmd === "/review") {
|
|
1960
|
+
logger.newline();
|
|
1961
|
+
await reviewCommand(options);
|
|
1962
|
+
return true;
|
|
1963
|
+
}
|
|
1964
|
+
if (mainCmd === "/explain") {
|
|
1965
|
+
const target = parts.slice(1).join(" ").trim();
|
|
1966
|
+
if (!target) {
|
|
1967
|
+
logger.error("Please provide something to explain. Example: /explain src/auth.ts");
|
|
1968
|
+
return true;
|
|
1969
|
+
}
|
|
1970
|
+
logger.newline();
|
|
1971
|
+
await explainCommand(target, options);
|
|
1972
|
+
return true;
|
|
1973
|
+
}
|
|
1974
|
+
if (mainCmd === "/memory") {
|
|
1975
|
+
const subCmd = parts[1]?.toLowerCase();
|
|
1976
|
+
if (subCmd === "save") {
|
|
1977
|
+
const content = parts.slice(2).join(" ").trim();
|
|
1978
|
+
if (!content) {
|
|
1979
|
+
logger.error("Please provide content to save. Example: /memory save Auth uses JWT");
|
|
1980
|
+
return true;
|
|
1981
|
+
}
|
|
1982
|
+
logger.newline();
|
|
1983
|
+
await memoryCommand("save", content, options);
|
|
1984
|
+
return true;
|
|
1985
|
+
}
|
|
1986
|
+
if (subCmd === "show") {
|
|
1987
|
+
logger.newline();
|
|
1988
|
+
await memoryCommand("show", void 0, options);
|
|
1989
|
+
return true;
|
|
1990
|
+
}
|
|
1991
|
+
if (subCmd === "clear") {
|
|
1992
|
+
logger.newline();
|
|
1993
|
+
await memoryCommand("clear", void 0, options);
|
|
1994
|
+
return true;
|
|
1995
|
+
}
|
|
1996
|
+
logger.error("Invalid memory command. Use: /memory save|show|clear");
|
|
1997
|
+
return true;
|
|
1998
|
+
}
|
|
1999
|
+
logger.warn(`Unknown command: ${mainCmd}. Type /help for available commands.`);
|
|
2000
|
+
return true;
|
|
2001
|
+
}
|
|
2002
|
+
function printWelcomeBanner() {
|
|
2003
|
+
logger.box([
|
|
2004
|
+
chalk3.bold.cyan("DevWing AI - Interactive Chat Mode"),
|
|
2005
|
+
"",
|
|
2006
|
+
"Chat with AI about your codebase. Type your message and press Enter.",
|
|
2007
|
+
"",
|
|
2008
|
+
chalk3.dim("Type /help for commands \u2022 /exit to quit")
|
|
2009
|
+
].join("\n"), { title: "\u{1F680} Welcome", color: "cyan" });
|
|
2010
|
+
}
|
|
2011
|
+
async function chatCommand(options) {
|
|
2012
|
+
try {
|
|
2013
|
+
const apiKey = await configManager.getApiKey();
|
|
2014
|
+
if (!apiKey) {
|
|
2015
|
+
logger.error('Not authenticated. Run "devwing login" first.');
|
|
2016
|
+
process.exit(1);
|
|
2017
|
+
}
|
|
2018
|
+
const session = new ChatSession();
|
|
2019
|
+
console.clear();
|
|
2020
|
+
printWelcomeBanner();
|
|
2021
|
+
logger.newline();
|
|
2022
|
+
const rl = readline.createInterface({
|
|
2023
|
+
input: process.stdin,
|
|
2024
|
+
output: process.stdout,
|
|
2025
|
+
prompt: chalk3.bold.green("You: ")
|
|
2026
|
+
});
|
|
2027
|
+
rl.on("SIGINT", () => {
|
|
2028
|
+
logger.newline();
|
|
2029
|
+
logger.info("Exiting chat mode...");
|
|
2030
|
+
rl.close();
|
|
2031
|
+
process.exit(0);
|
|
2032
|
+
});
|
|
2033
|
+
logger.startSpinner("Loading codebase context...");
|
|
2034
|
+
const collector = new ContextCollector(process.cwd());
|
|
2035
|
+
const initialContext = await collector.collect("");
|
|
2036
|
+
session.setContext(initialContext);
|
|
2037
|
+
logger.succeedSpinner("Context loaded!");
|
|
2038
|
+
logger.newline();
|
|
2039
|
+
rl.prompt();
|
|
2040
|
+
rl.on("line", async (input) => {
|
|
2041
|
+
const userMessage = input.trim();
|
|
2042
|
+
if (!userMessage) {
|
|
2043
|
+
rl.prompt();
|
|
2044
|
+
return;
|
|
2045
|
+
}
|
|
2046
|
+
if (userMessage.startsWith("/")) {
|
|
2047
|
+
const shouldContinue = await handleSpecialCommand(userMessage, session, options);
|
|
2048
|
+
if (!shouldContinue) {
|
|
2049
|
+
rl.close();
|
|
2050
|
+
return;
|
|
2051
|
+
}
|
|
2052
|
+
logger.newline();
|
|
2053
|
+
rl.prompt();
|
|
2054
|
+
return;
|
|
2055
|
+
}
|
|
2056
|
+
session.addMessage("user", userMessage);
|
|
2057
|
+
logger.newline();
|
|
2058
|
+
logger.info(chalk3.dim("DevWing is thinking..."));
|
|
2059
|
+
logger.newline();
|
|
2060
|
+
try {
|
|
2061
|
+
const request = {
|
|
2062
|
+
prompt: buildPromptWithHistory(session),
|
|
2063
|
+
mode: options.mode,
|
|
2064
|
+
model: options.model,
|
|
2065
|
+
project_id: options.project || configManager.getProjectId(),
|
|
2066
|
+
context: session.getContext(),
|
|
2067
|
+
stream: true,
|
|
2068
|
+
max_tokens: 4096
|
|
2069
|
+
};
|
|
2070
|
+
let assistantResponse = "";
|
|
2071
|
+
streamingRenderer.reset();
|
|
2072
|
+
streamingRenderer.clearPendingTools();
|
|
2073
|
+
for await (const message of apiClient.streamCompletion(request)) {
|
|
2074
|
+
await streamingRenderer.processMessage(message);
|
|
2075
|
+
if (message.type === "token" && message.content) {
|
|
2076
|
+
assistantResponse += message.content;
|
|
2077
|
+
}
|
|
2078
|
+
if (message.session_id) {
|
|
2079
|
+
session.setSessionId(message.session_id);
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
if (assistantResponse) {
|
|
2083
|
+
session.addMessage("assistant", assistantResponse);
|
|
2084
|
+
}
|
|
2085
|
+
const pendingTools = streamingRenderer.getPendingToolCalls();
|
|
2086
|
+
if (pendingTools.length > 0) {
|
|
2087
|
+
logger.newline();
|
|
2088
|
+
logger.info("Executing tools...");
|
|
2089
|
+
const toolResults = await streamingRenderer.executePendingTools();
|
|
2090
|
+
if (session.getSessionId()) {
|
|
2091
|
+
for await (const message of apiClient.continueCompletion(session.getSessionId(), toolResults)) {
|
|
2092
|
+
await streamingRenderer.processMessage(message);
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
logger.newline();
|
|
2097
|
+
logger.newline();
|
|
2098
|
+
} catch (error) {
|
|
2099
|
+
logger.newline();
|
|
2100
|
+
logger.error("Error:", error.message || error);
|
|
2101
|
+
logger.newline();
|
|
2102
|
+
}
|
|
2103
|
+
rl.prompt();
|
|
2104
|
+
});
|
|
2105
|
+
rl.on("close", () => {
|
|
2106
|
+
logger.newline();
|
|
2107
|
+
logger.success("Chat session ended. Goodbye!");
|
|
2108
|
+
process.exit(0);
|
|
2109
|
+
});
|
|
2110
|
+
} catch (error) {
|
|
2111
|
+
logger.error("Chat command failed", error);
|
|
2112
|
+
process.exit(1);
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
function buildPromptWithHistory(session) {
|
|
2116
|
+
const history = session.getHistory();
|
|
2117
|
+
if (history.length === 0) {
|
|
2118
|
+
return "";
|
|
2119
|
+
}
|
|
2120
|
+
const lastUserMessage = history[history.length - 1];
|
|
2121
|
+
if (history.length === 1) {
|
|
2122
|
+
return lastUserMessage.content;
|
|
2123
|
+
}
|
|
2124
|
+
const recentHistory = history.slice(-10);
|
|
2125
|
+
const historyContext = recentHistory.slice(0, -1).map((msg) => `${msg.role === "user" ? "User" : "Assistant"}: ${msg.content}`).join("\n\n");
|
|
2126
|
+
return `Previous conversation:
|
|
2127
|
+
${historyContext}
|
|
2128
|
+
|
|
2129
|
+
Current question:
|
|
2130
|
+
${lastUserMessage.content}`;
|
|
2131
|
+
}
|
|
2072
2132
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
2073
2133
|
var __dirname2 = dirname(__filename2);
|
|
2074
2134
|
function getCurrentVersion() {
|
|
@@ -2215,7 +2275,7 @@ async function updateCommand(options) {
|
|
|
2215
2275
|
|
|
2216
2276
|
// src/index.ts
|
|
2217
2277
|
var program = new Command();
|
|
2218
|
-
var VERSION = "0.1.
|
|
2278
|
+
var VERSION = "0.1.4";
|
|
2219
2279
|
program.name("devwing").description("DevWing.ai - Your AI Wingman in the Terminal").version(VERSION, "-v, --version", "Display version number").helpOption("-h, --help", "Display help information");
|
|
2220
2280
|
program.option("--mode <mode>", "AI mode: general|frontend|backend|security|devops").option("--model <model>", "Specific model to use").option("--project <id>", "Project ID").option("--workspace <id>", "Workspace ID").option("--verbose", "Verbose output for debugging").option("-y, --yes", "Auto-confirm destructive actions");
|
|
2221
2281
|
program.command("login").description("Authenticate with DevWing").action(async () => {
|
|
@@ -2269,13 +2329,13 @@ configCmd.command("set <key> <value>").description("Set configuration value").ac
|
|
|
2269
2329
|
program.command("update").description("Check for and install CLI updates").option("--check", "Only check for updates, do not install").option("--force", "Skip confirmation prompt").action(async (options) => {
|
|
2270
2330
|
await updateCommand(options);
|
|
2271
2331
|
});
|
|
2272
|
-
program.argument("[prompt...]", "Natural language prompt for AI").action(async (promptParts) => {
|
|
2332
|
+
program.argument("[prompt...]", "Natural language prompt for AI (optional - starts chat mode if empty)").action(async (promptParts) => {
|
|
2333
|
+
const opts = program.opts();
|
|
2273
2334
|
if (promptParts.length === 0) {
|
|
2274
|
-
|
|
2335
|
+
await chatCommand(opts);
|
|
2275
2336
|
return;
|
|
2276
2337
|
}
|
|
2277
2338
|
const prompt = promptParts.join(" ");
|
|
2278
|
-
const opts = program.opts();
|
|
2279
2339
|
await promptCommand(prompt, opts);
|
|
2280
2340
|
});
|
|
2281
2341
|
program.exitOverride();
|