wave-code 0.0.2

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.
Files changed (131) hide show
  1. package/README.md +120 -0
  2. package/bin/wave-code.js +16 -0
  3. package/dist/cli.d.ts +6 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +62 -0
  6. package/dist/components/App.d.ts +8 -0
  7. package/dist/components/App.d.ts.map +1 -0
  8. package/dist/components/App.js +10 -0
  9. package/dist/components/BashHistorySelector.d.ts +10 -0
  10. package/dist/components/BashHistorySelector.d.ts.map +1 -0
  11. package/dist/components/BashHistorySelector.js +83 -0
  12. package/dist/components/BashShellManager.d.ts +6 -0
  13. package/dist/components/BashShellManager.d.ts.map +1 -0
  14. package/dist/components/BashShellManager.js +116 -0
  15. package/dist/components/ChatInterface.d.ts +3 -0
  16. package/dist/components/ChatInterface.d.ts.map +1 -0
  17. package/dist/components/ChatInterface.js +31 -0
  18. package/dist/components/CommandOutputDisplay.d.ts +9 -0
  19. package/dist/components/CommandOutputDisplay.d.ts.map +1 -0
  20. package/dist/components/CommandOutputDisplay.js +40 -0
  21. package/dist/components/CommandSelector.d.ts +11 -0
  22. package/dist/components/CommandSelector.d.ts.map +1 -0
  23. package/dist/components/CommandSelector.js +60 -0
  24. package/dist/components/CompressDisplay.d.ts +9 -0
  25. package/dist/components/CompressDisplay.d.ts.map +1 -0
  26. package/dist/components/CompressDisplay.js +17 -0
  27. package/dist/components/DiffViewer.d.ts +9 -0
  28. package/dist/components/DiffViewer.d.ts.map +1 -0
  29. package/dist/components/DiffViewer.js +221 -0
  30. package/dist/components/FileSelector.d.ts +13 -0
  31. package/dist/components/FileSelector.d.ts.map +1 -0
  32. package/dist/components/FileSelector.js +48 -0
  33. package/dist/components/InputBox.d.ts +23 -0
  34. package/dist/components/InputBox.d.ts.map +1 -0
  35. package/dist/components/InputBox.js +124 -0
  36. package/dist/components/McpManager.d.ts +10 -0
  37. package/dist/components/McpManager.d.ts.map +1 -0
  38. package/dist/components/McpManager.js +123 -0
  39. package/dist/components/MemoryDisplay.d.ts +8 -0
  40. package/dist/components/MemoryDisplay.d.ts.map +1 -0
  41. package/dist/components/MemoryDisplay.js +25 -0
  42. package/dist/components/MemoryTypeSelector.d.ts +8 -0
  43. package/dist/components/MemoryTypeSelector.d.ts.map +1 -0
  44. package/dist/components/MemoryTypeSelector.js +38 -0
  45. package/dist/components/MessageList.d.ts +12 -0
  46. package/dist/components/MessageList.d.ts.map +1 -0
  47. package/dist/components/MessageList.js +36 -0
  48. package/dist/components/ToolResultDisplay.d.ts +9 -0
  49. package/dist/components/ToolResultDisplay.d.ts.map +1 -0
  50. package/dist/components/ToolResultDisplay.js +52 -0
  51. package/dist/contexts/useAppConfig.d.ts +11 -0
  52. package/dist/contexts/useAppConfig.d.ts.map +1 -0
  53. package/dist/contexts/useAppConfig.js +13 -0
  54. package/dist/contexts/useChat.d.ts +36 -0
  55. package/dist/contexts/useChat.d.ts.map +1 -0
  56. package/dist/contexts/useChat.js +208 -0
  57. package/dist/hooks/useBashHistorySelector.d.ts +15 -0
  58. package/dist/hooks/useBashHistorySelector.d.ts.map +1 -0
  59. package/dist/hooks/useBashHistorySelector.js +61 -0
  60. package/dist/hooks/useCommandSelector.d.ts +24 -0
  61. package/dist/hooks/useCommandSelector.d.ts.map +1 -0
  62. package/dist/hooks/useCommandSelector.js +98 -0
  63. package/dist/hooks/useFileSelector.d.ts +16 -0
  64. package/dist/hooks/useFileSelector.d.ts.map +1 -0
  65. package/dist/hooks/useFileSelector.js +174 -0
  66. package/dist/hooks/useImageManager.d.ts +13 -0
  67. package/dist/hooks/useImageManager.d.ts.map +1 -0
  68. package/dist/hooks/useImageManager.js +46 -0
  69. package/dist/hooks/useInputHistory.d.ts +11 -0
  70. package/dist/hooks/useInputHistory.d.ts.map +1 -0
  71. package/dist/hooks/useInputHistory.js +64 -0
  72. package/dist/hooks/useInputKeyboardHandler.d.ts +83 -0
  73. package/dist/hooks/useInputKeyboardHandler.d.ts.map +1 -0
  74. package/dist/hooks/useInputKeyboardHandler.js +507 -0
  75. package/dist/hooks/useInputState.d.ts +14 -0
  76. package/dist/hooks/useInputState.d.ts.map +1 -0
  77. package/dist/hooks/useInputState.js +57 -0
  78. package/dist/hooks/useMemoryTypeSelector.d.ts +9 -0
  79. package/dist/hooks/useMemoryTypeSelector.d.ts.map +1 -0
  80. package/dist/hooks/useMemoryTypeSelector.js +27 -0
  81. package/dist/hooks/usePagination.d.ts +20 -0
  82. package/dist/hooks/usePagination.d.ts.map +1 -0
  83. package/dist/hooks/usePagination.js +168 -0
  84. package/dist/index.d.ts +5 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +91 -0
  87. package/dist/plain-cli.d.ts +7 -0
  88. package/dist/plain-cli.d.ts.map +1 -0
  89. package/dist/plain-cli.js +49 -0
  90. package/dist/utils/clipboard.d.ts +22 -0
  91. package/dist/utils/clipboard.d.ts.map +1 -0
  92. package/dist/utils/clipboard.js +347 -0
  93. package/dist/utils/constants.d.ts +17 -0
  94. package/dist/utils/constants.d.ts.map +1 -0
  95. package/dist/utils/constants.js +18 -0
  96. package/dist/utils/logger.d.ts +72 -0
  97. package/dist/utils/logger.d.ts.map +1 -0
  98. package/dist/utils/logger.js +245 -0
  99. package/package.json +60 -0
  100. package/src/cli.tsx +82 -0
  101. package/src/components/App.tsx +31 -0
  102. package/src/components/BashHistorySelector.tsx +163 -0
  103. package/src/components/BashShellManager.tsx +306 -0
  104. package/src/components/ChatInterface.tsx +88 -0
  105. package/src/components/CommandOutputDisplay.tsx +81 -0
  106. package/src/components/CommandSelector.tsx +144 -0
  107. package/src/components/CompressDisplay.tsx +58 -0
  108. package/src/components/DiffViewer.tsx +321 -0
  109. package/src/components/FileSelector.tsx +137 -0
  110. package/src/components/InputBox.tsx +310 -0
  111. package/src/components/McpManager.tsx +328 -0
  112. package/src/components/MemoryDisplay.tsx +62 -0
  113. package/src/components/MemoryTypeSelector.tsx +96 -0
  114. package/src/components/MessageList.tsx +215 -0
  115. package/src/components/ToolResultDisplay.tsx +138 -0
  116. package/src/contexts/useAppConfig.tsx +32 -0
  117. package/src/contexts/useChat.tsx +300 -0
  118. package/src/hooks/useBashHistorySelector.ts +77 -0
  119. package/src/hooks/useCommandSelector.ts +131 -0
  120. package/src/hooks/useFileSelector.ts +227 -0
  121. package/src/hooks/useImageManager.ts +64 -0
  122. package/src/hooks/useInputHistory.ts +74 -0
  123. package/src/hooks/useInputKeyboardHandler.ts +778 -0
  124. package/src/hooks/useInputState.ts +66 -0
  125. package/src/hooks/useMemoryTypeSelector.ts +40 -0
  126. package/src/hooks/usePagination.ts +203 -0
  127. package/src/index.ts +108 -0
  128. package/src/plain-cli.ts +66 -0
  129. package/src/utils/clipboard.ts +384 -0
  130. package/src/utils/constants.ts +22 -0
  131. package/src/utils/logger.ts +301 -0
@@ -0,0 +1,168 @@
1
+ import { useState, useEffect, useMemo } from "react";
2
+ import { useInput } from "ink";
3
+ import { MESSAGES_PER_PAGE } from "../utils/constants.js";
4
+ export const usePagination = (messages) => {
5
+ const messagesPerPage = MESSAGES_PER_PAGE;
6
+ // Calculate pagination info, ensuring first page can be incomplete while subsequent pages are complete
7
+ const paginationInfo = useMemo(() => {
8
+ if (messages.length <= messagesPerPage) {
9
+ // If total messages don't exceed one page, display all messages directly
10
+ return {
11
+ currentPage: 1,
12
+ totalPages: 1,
13
+ startIndex: 0,
14
+ endIndex: messages.length,
15
+ messagesPerPage,
16
+ };
17
+ }
18
+ // Calculate remaining messages (messages other than the first page)
19
+ const remainingMessages = messages.length % messagesPerPage;
20
+ if (remainingMessages === 0) {
21
+ // Message count fits perfectly into complete pages, use standard pagination
22
+ const totalPages = Math.ceil(messages.length / messagesPerPage);
23
+ const currentPage = totalPages;
24
+ const startIndex = (currentPage - 1) * messagesPerPage;
25
+ const endIndex = messages.length;
26
+ return {
27
+ currentPage,
28
+ totalPages,
29
+ startIndex,
30
+ endIndex,
31
+ messagesPerPage,
32
+ };
33
+ }
34
+ else {
35
+ // Has remaining messages, let first page display remaining messages, subsequent pages are complete
36
+ const firstPageMessageCount = remainingMessages;
37
+ const totalPages = Math.floor(messages.length / messagesPerPage) + 1;
38
+ // Default to showing the last page (complete page)
39
+ const currentPage = totalPages;
40
+ const startIndex = firstPageMessageCount + (currentPage - 2) * messagesPerPage;
41
+ const endIndex = messages.length;
42
+ return {
43
+ currentPage,
44
+ totalPages,
45
+ startIndex,
46
+ endIndex,
47
+ messagesPerPage,
48
+ };
49
+ }
50
+ }, [messages.length, messagesPerPage]);
51
+ // Manually controlled current page (for keyboard navigation)
52
+ const [manualPage, setManualPage] = useState(null);
53
+ // Calculate actual display page info
54
+ const displayInfo = useMemo(() => {
55
+ if (manualPage === null) {
56
+ return paginationInfo; // Auto mode: display last page
57
+ }
58
+ // Manual mode: display user-selected page
59
+ const totalPages = paginationInfo.totalPages;
60
+ const currentPage = Math.min(Math.max(1, manualPage), totalPages);
61
+ if (messages.length <= messagesPerPage) {
62
+ // Only one page case
63
+ return {
64
+ currentPage,
65
+ totalPages,
66
+ startIndex: 0,
67
+ endIndex: messages.length,
68
+ messagesPerPage,
69
+ };
70
+ }
71
+ const remainingMessages = messages.length % messagesPerPage;
72
+ if (remainingMessages === 0) {
73
+ // Message count fits perfectly into complete pages
74
+ const startIndex = (currentPage - 1) * messagesPerPage;
75
+ const endIndex = Math.min(startIndex + messagesPerPage, messages.length);
76
+ return {
77
+ currentPage,
78
+ totalPages,
79
+ startIndex,
80
+ endIndex,
81
+ messagesPerPage,
82
+ };
83
+ }
84
+ else {
85
+ // First page incomplete, subsequent pages complete
86
+ if (currentPage === 1) {
87
+ // First page: display remaining message count
88
+ return {
89
+ currentPage,
90
+ totalPages,
91
+ startIndex: 0,
92
+ endIndex: remainingMessages,
93
+ messagesPerPage,
94
+ };
95
+ }
96
+ else {
97
+ // Other pages: display complete message count per page
98
+ const firstPageMessageCount = remainingMessages;
99
+ const startIndex = firstPageMessageCount + (currentPage - 2) * messagesPerPage;
100
+ const endIndex = Math.min(startIndex + messagesPerPage, messages.length);
101
+ return {
102
+ currentPage,
103
+ totalPages,
104
+ startIndex,
105
+ endIndex,
106
+ messagesPerPage,
107
+ };
108
+ }
109
+ }
110
+ }, [messages.length, messagesPerPage, manualPage, paginationInfo]);
111
+ // When message count changes, if user hasn't manually navigated, reset to auto mode
112
+ useEffect(() => {
113
+ if (manualPage !== null) {
114
+ // If user is currently on the last page, keep auto mode
115
+ const totalPages = Math.ceil(messages.length / messagesPerPage);
116
+ if (manualPage >= totalPages) {
117
+ setManualPage(null);
118
+ }
119
+ }
120
+ }, [messages.length, messagesPerPage, manualPage]);
121
+ // Pagination functionality
122
+ const goToPage = (page) => {
123
+ setManualPage(page);
124
+ };
125
+ const goToPrevPage = () => {
126
+ const currentPage = manualPage ?? displayInfo.currentPage;
127
+ setManualPage(Math.max(1, currentPage - 1));
128
+ };
129
+ const goToNextPage = () => {
130
+ const currentPage = manualPage ?? displayInfo.currentPage;
131
+ setManualPage(Math.min(displayInfo.totalPages, currentPage + 1));
132
+ };
133
+ const goToFirstPage = () => {
134
+ setManualPage(1);
135
+ };
136
+ const goToLastPage = () => {
137
+ setManualPage(null); // Return to auto mode (last page)
138
+ };
139
+ // Integrate keyboard shortcut handling
140
+ useInput((input, key) => {
141
+ // Ctrl+U/D shortcuts (Vim/Less style)
142
+ if (key.ctrl) {
143
+ if (input === "u") {
144
+ goToPrevPage();
145
+ }
146
+ else if (input === "d") {
147
+ goToNextPage();
148
+ }
149
+ }
150
+ // Page Up/Down support
151
+ if (key.pageUp) {
152
+ goToPrevPage();
153
+ }
154
+ if (key.pageDown) {
155
+ goToNextPage();
156
+ }
157
+ });
158
+ return {
159
+ displayInfo,
160
+ manualPage,
161
+ setManualPage,
162
+ goToPage,
163
+ goToPrevPage,
164
+ goToNextPage,
165
+ goToFirstPage,
166
+ goToLastPage,
167
+ };
168
+ };
@@ -0,0 +1,5 @@
1
+ export declare function main(): Promise<void>;
2
+ export { startCli } from "./cli.js";
3
+ export { logger } from "./utils/logger.js";
4
+ export { readClipboardImage, cleanupTempImage, hasClipboardImage, type ClipboardImageResult, } from "./utils/clipboard.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,wBAAsB,IAAI,kBA+EzB;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,91 @@
1
+ import yargs from "yargs";
2
+ import { hideBin } from "yargs/helpers";
3
+ import { startCli } from "./cli.js";
4
+ import { listSessions } from "wave-agent-sdk";
5
+ // Export main function for external use
6
+ export async function main() {
7
+ const argv = await yargs(hideBin(process.argv))
8
+ .option("restore", {
9
+ alias: "r",
10
+ description: "Restore session by ID",
11
+ type: "string",
12
+ })
13
+ .option("continue", {
14
+ alias: "c",
15
+ description: "Continue from last session",
16
+ type: "boolean",
17
+ })
18
+ .option("plain", {
19
+ alias: "p",
20
+ description: "Plain mode with message to send",
21
+ type: "string",
22
+ })
23
+ .option("list-sessions", {
24
+ description: "List all available sessions",
25
+ type: "boolean",
26
+ })
27
+ .version()
28
+ .alias("v", "version")
29
+ .example("$0", "Start CLI with default settings")
30
+ .example("$0 --restore session_123", "Restore specific session")
31
+ .example("$0 --continue", "Continue from last session")
32
+ .example("$0 --plain 'Hello'", "Send message in plain mode")
33
+ .example("$0 -p 'Hello'", "Send message in plain mode (short)")
34
+ .example("$0 --list-sessions", "List all available sessions")
35
+ .help("h")
36
+ .parseAsync();
37
+ // Handle list sessions command
38
+ if (argv.listSessions) {
39
+ try {
40
+ const currentWorkdir = process.cwd();
41
+ const sessions = await listSessions(currentWorkdir);
42
+ if (sessions.length === 0) {
43
+ console.log(`No sessions found for workdir: ${currentWorkdir}`);
44
+ return;
45
+ }
46
+ console.log(`Available sessions for: ${currentWorkdir}`);
47
+ console.log("==========================================");
48
+ for (const session of sessions) {
49
+ const startedAt = new Date(session.startedAt).toLocaleString();
50
+ const lastActiveAt = new Date(session.lastActiveAt).toLocaleString();
51
+ console.log(`ID: ${session.id}`);
52
+ console.log(` Workdir: ${session.workdir}`);
53
+ console.log(` Started: ${startedAt}`);
54
+ console.log(` Last Active: ${lastActiveAt}`);
55
+ console.log(` Last Message Tokens: ${session.latestTotalTokens}`);
56
+ console.log("");
57
+ }
58
+ return;
59
+ }
60
+ catch (error) {
61
+ console.error("Failed to list sessions:", error);
62
+ process.exit(1);
63
+ }
64
+ }
65
+ // Handle plain mode directly
66
+ if (argv.plain !== undefined) {
67
+ const { startPlainCli } = await import("./plain-cli.js");
68
+ return startPlainCli({
69
+ restoreSessionId: argv.restore,
70
+ continueLastSession: argv.continue,
71
+ message: argv.plain,
72
+ });
73
+ }
74
+ await startCli({
75
+ restoreSessionId: argv.restore,
76
+ continueLastSession: argv.continue,
77
+ });
78
+ }
79
+ // Export CLI function
80
+ export { startCli } from "./cli.js";
81
+ // Export logger
82
+ export { logger } from "./utils/logger.js";
83
+ // Export clipboard utilities
84
+ export { readClipboardImage, cleanupTempImage, hasClipboardImage, } from "./utils/clipboard.js";
85
+ // Execute main function if this file is run directly
86
+ if (import.meta.url === `file://${process.argv[1]}`) {
87
+ main().catch((error) => {
88
+ console.error("Failed to start WAVE Code:", error);
89
+ process.exit(1);
90
+ });
91
+ }
@@ -0,0 +1,7 @@
1
+ export interface PlainCliOptions {
2
+ restoreSessionId?: string;
3
+ continueLastSession?: boolean;
4
+ message?: string;
5
+ }
6
+ export declare function startPlainCli(options: PlainCliOptions): Promise<void>;
7
+ //# sourceMappingURL=plain-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plain-cli.d.ts","sourceRoot":"","sources":["../src/plain-cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwD3E"}
@@ -0,0 +1,49 @@
1
+ import { Agent } from "wave-agent-sdk";
2
+ import { logger } from "./utils/logger.js";
3
+ export async function startPlainCli(options) {
4
+ const { restoreSessionId, continueLastSession, message } = options;
5
+ if ((!message || message.trim() === "") &&
6
+ !continueLastSession &&
7
+ !restoreSessionId) {
8
+ console.error("Plain mode requires a message: use --plain 'your message' or -p 'your message'");
9
+ process.exit(1);
10
+ }
11
+ let agent;
12
+ let lastAssistantMessage;
13
+ // Setup callbacks for agent
14
+ const callbacks = {
15
+ onAssistantMessageAdded: (content) => {
16
+ // Store the content instead of immediately printing it
17
+ if (content) {
18
+ lastAssistantMessage = content;
19
+ }
20
+ },
21
+ };
22
+ try {
23
+ // Initialize agent
24
+ agent = await Agent.create({
25
+ callbacks,
26
+ restoreSessionId,
27
+ continueLastSession,
28
+ logger,
29
+ });
30
+ // Send message if provided and not empty
31
+ if (message && message.trim() !== "") {
32
+ await agent.sendMessage(message);
33
+ }
34
+ // Output only the last assistant message
35
+ if (lastAssistantMessage) {
36
+ console.log(lastAssistantMessage);
37
+ }
38
+ // Destroy agent and exit after sendMessage completes
39
+ agent.destroy();
40
+ process.exit(0);
41
+ }
42
+ catch (error) {
43
+ console.error("Failed to send message:", error);
44
+ if (agent) {
45
+ agent.destroy();
46
+ }
47
+ process.exit(1);
48
+ }
49
+ }
@@ -0,0 +1,22 @@
1
+ export interface ClipboardImageResult {
2
+ success: boolean;
3
+ imagePath?: string;
4
+ error?: string;
5
+ mimeType?: string;
6
+ }
7
+ /**
8
+ * Read image from clipboard
9
+ * @returns Promise<ClipboardImageResult> Result containing image path or error information
10
+ */
11
+ export declare function readClipboardImage(): Promise<ClipboardImageResult>;
12
+ /**
13
+ * Clean up temporary image file
14
+ * @param imagePath Path to the image file to clean up
15
+ */
16
+ export declare function cleanupTempImage(imagePath: string): void;
17
+ /**
18
+ * Check if clipboard contains image (quick check, does not save file)
19
+ * @returns Promise<boolean> Whether it contains image
20
+ */
21
+ export declare function hasClipboardImage(): Promise<boolean>;
22
+ //# sourceMappingURL=clipboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipboard.d.ts","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAsBxE;AAsOD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAQxD;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAgB1D"}