hypercore-cli 1.1.1 → 1.3.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.
Files changed (158) hide show
  1. package/LICENSE +92 -21
  2. package/README.md +8 -1
  3. package/dist/App-YMX7FSXR.js +1 -0
  4. package/dist/api-Q2TX5JJL.js +1 -0
  5. package/dist/auth-X6CUT3DW.js +1 -0
  6. package/dist/background-ACODXSUG.js +1 -0
  7. package/dist/backlog-JD2IM336.js +1 -0
  8. package/dist/chunk-2QI2IU2V.js +1 -0
  9. package/dist/chunk-3KFRDIPQ.js +1 -0
  10. package/dist/chunk-42C5J7PN.js +1 -0
  11. package/dist/chunk-4D7XVJ7Q.js +1 -0
  12. package/dist/chunk-545IGTXV.js +1 -0
  13. package/dist/chunk-5KUSGQP2.js +1 -0
  14. package/dist/chunk-AUQ64BK2.js +1 -0
  15. package/dist/chunk-AV244H5C.js +1 -0
  16. package/dist/chunk-BQVBEFS4.js +1 -0
  17. package/dist/chunk-BYWQLFP2.js +1 -0
  18. package/dist/chunk-COITWWZJ.js +1 -0
  19. package/dist/chunk-CR7UUJVX.js +1 -0
  20. package/dist/chunk-E3MULLBX.js +1 -0
  21. package/dist/chunk-EWBV7YPP.js +1 -0
  22. package/dist/chunk-EZHYVJGQ.js +1 -0
  23. package/dist/chunk-FAKXBY7Q.js +1 -0
  24. package/dist/chunk-FHGATV5B.js +1 -0
  25. package/dist/chunk-I2G27Y5P.js +1 -0
  26. package/dist/chunk-IKF43TX2.js +1 -0
  27. package/dist/chunk-INSPHCBN.js +1 -0
  28. package/dist/chunk-LQMDUKIE.js +1 -0
  29. package/dist/chunk-M3MTKGA5.js +1 -0
  30. package/dist/chunk-MPO54FU3.js +1 -0
  31. package/dist/chunk-PVKCZI6A.js +1 -0
  32. package/dist/chunk-Q7KEPCYL.js +1 -0
  33. package/dist/chunk-R5XD3NT2.js +1 -0
  34. package/dist/chunk-ROBZ6PAL.js +1 -0
  35. package/dist/chunk-RXB5BS2N.js +1 -0
  36. package/dist/chunk-RZ3HNYMT.js +1 -0
  37. package/dist/chunk-UCGLRMTG.js +1 -0
  38. package/dist/chunk-UEHJVRKB.js +1 -0
  39. package/dist/chunk-UZYX5GGF.js +1 -0
  40. package/dist/chunk-XQJBB725.js +1 -0
  41. package/dist/chunk-ZB5ZQSXH.js +1 -0
  42. package/dist/claude-US2QPRBA.js +1 -0
  43. package/dist/commands-5TFN74MD.js +1 -0
  44. package/dist/commands-EKPWCB3T.js +1 -0
  45. package/dist/commands-QHJLREPM.js +1 -0
  46. package/dist/config-2OUL5FLS.js +1 -0
  47. package/dist/config-loader-N7IBWN2P.js +1 -0
  48. package/dist/diagnose-NLHN4SAJ.js +1 -0
  49. package/dist/display-TB5YACJV.js +1 -0
  50. package/dist/extractor-3KTM2IUL.js +1 -0
  51. package/dist/feature-flag-VVIF5FJG.js +1 -0
  52. package/dist/history-GVNDPXXQ.js +1 -0
  53. package/dist/index.js +1 -402
  54. package/dist/instance-registry-I5AIVJE2.js +1 -0
  55. package/dist/keybindings-RN3A7CRW.js +1 -0
  56. package/dist/loader-3IKPXP4R.js +1 -0
  57. package/dist/network-GI2F3IDE.js +1 -0
  58. package/dist/notify-O6FNVHC4.js +1 -0
  59. package/dist/openai-compat-IPCMINVF.js +1 -0
  60. package/dist/permissions-5O7KVAXU.js +1 -0
  61. package/dist/prompt-VWFPFM4N.js +1 -0
  62. package/dist/quality-GPQD25UL.js +1 -0
  63. package/dist/repl-YNXCDVU4.js +1 -0
  64. package/dist/roadmap-QRZODSNJ.js +1 -0
  65. package/dist/server-USQP4GC4.js +1 -0
  66. package/dist/session-5HDDQQP6.js +1 -0
  67. package/dist/skills-DXWSVJSU.js +1 -0
  68. package/dist/store-WXXTKTTL.js +1 -0
  69. package/dist/team-VTPJ3WRT.js +1 -0
  70. package/dist/telemetry-NT4UZLBS.js +1 -0
  71. package/dist/test-runner-F6B6RH3S.js +1 -0
  72. package/dist/theme-JJJ6ABR2.js +1 -0
  73. package/dist/upgrade-RUG3R7R5.js +1 -0
  74. package/dist/verify-6OGRY2PR.js +1 -0
  75. package/dist/version-DLROA5JN.js +1 -0
  76. package/dist/web/static/app.js +1 -562
  77. package/dist/web/static/index.html +114 -126
  78. package/dist/web/static/mirror.css +1 -1001
  79. package/dist/web/static/mirror.html +155 -178
  80. package/dist/web/static/mirror.js +1 -1125
  81. package/dist/web/static/onboard.css +1 -302
  82. package/dist/web/static/onboard.html +121 -145
  83. package/dist/web/static/onboard.js +1 -300
  84. package/dist/web/static/style.css +1 -602
  85. package/dist/web/static/utils.js +1 -0
  86. package/dist/web/static/workspace.css +1 -1568
  87. package/dist/web/static/workspace.html +369 -402
  88. package/dist/web/static/workspace.js +1 -1683
  89. package/dist/web-P5YUKEAU.js +1 -0
  90. package/package.json +25 -4
  91. package/dist/api-D4PUN5BN.js +0 -162
  92. package/dist/auth-UTR4I6QY.js +0 -21
  93. package/dist/background-2EGCAAQH.js +0 -14
  94. package/dist/backlog-Q2NZCLNY.js +0 -24
  95. package/dist/chunk-2CMSCWQW.js +0 -162
  96. package/dist/chunk-4DVYJAJL.js +0 -57
  97. package/dist/chunk-77FRUHTU.js +0 -271
  98. package/dist/chunk-7ZYMJFCA.js +0 -251
  99. package/dist/chunk-BE46C7JW.js +0 -46
  100. package/dist/chunk-CM423E2U.js +0 -133
  101. package/dist/chunk-E4NKO2KI.js +0 -263
  102. package/dist/chunk-GH7E2OJE.js +0 -223
  103. package/dist/chunk-GMLQ7GZ5.js +0 -134
  104. package/dist/chunk-GU2FZQ6A.js +0 -69
  105. package/dist/chunk-IOPKN5GD.js +0 -190
  106. package/dist/chunk-LWDNLX6B.js +0 -2025
  107. package/dist/chunk-MGLJ53QN.js +0 -219
  108. package/dist/chunk-NHPDLYEW.js +0 -139
  109. package/dist/chunk-OGQGKMDX.js +0 -173
  110. package/dist/chunk-OPZYEVYR.js +0 -150
  111. package/dist/chunk-OWAOKDIN.js +0 -1505
  112. package/dist/chunk-R3GPQC7I.js +0 -393
  113. package/dist/chunk-RKB2JOV2.js +0 -43
  114. package/dist/chunk-RNG3K465.js +0 -80
  115. package/dist/chunk-SHJQMIJL.js +0 -288
  116. package/dist/chunk-SVF2VWOZ.js +0 -145
  117. package/dist/chunk-TGTYKBGC.js +0 -86
  118. package/dist/chunk-V2EBSFPU.js +0 -575
  119. package/dist/chunk-VJDQNNSO.js +0 -681
  120. package/dist/chunk-VQ35XX7B.js +0 -167
  121. package/dist/chunk-WHLVZCQY.js +0 -245
  122. package/dist/chunk-XMGHVNH2.js +0 -66
  123. package/dist/chunk-YWOSOTUO.js +0 -58
  124. package/dist/chunk-ZQRNV2US.js +0 -166
  125. package/dist/chunk-ZSBHUGWR.js +0 -262
  126. package/dist/claude-O5FSOXZC.js +0 -12
  127. package/dist/commands-43PLOWRU.js +0 -128
  128. package/dist/commands-5YVUSUMP.js +0 -232
  129. package/dist/commands-VZMZJFZF.js +0 -1044
  130. package/dist/config-WXXEEEVW.js +0 -8
  131. package/dist/config-loader-SXO674TF.js +0 -24
  132. package/dist/diagnose-BX45APUZ.js +0 -12
  133. package/dist/display-IIUBEYWN.js +0 -58
  134. package/dist/extractor-R5ABXNTJ.js +0 -129
  135. package/dist/history-JPXZEOT3.js +0 -180
  136. package/dist/index.d.ts +0 -1
  137. package/dist/instance-registry-6NJTCAE4.js +0 -15
  138. package/dist/keybindings-ADWNOX5M.js +0 -15
  139. package/dist/loader-AXDDCB2G.js +0 -58
  140. package/dist/network-V3O4UZYZ.js +0 -279
  141. package/dist/notify-HPTALZDC.js +0 -14
  142. package/dist/openai-compat-UFDV2SCK.js +0 -12
  143. package/dist/permissions-JUKXMNDH.js +0 -10
  144. package/dist/prompt-5CZ34WGA.js +0 -166
  145. package/dist/quality-ST7PPNFR.js +0 -16
  146. package/dist/repl-EOWP6AAB.js +0 -3374
  147. package/dist/roadmap-5OBEKROY.js +0 -17
  148. package/dist/server-BB5AENWU.js +0 -57
  149. package/dist/session-5NDKKFLN.js +0 -21
  150. package/dist/skills-JVLIQVJN.js +0 -175
  151. package/dist/store-G7KRD4PN.js +0 -25
  152. package/dist/team-FVNNVDBY.js +0 -385
  153. package/dist/telemetry-6R4EIE6O.js +0 -30
  154. package/dist/test-runner-REKSVPPY.js +0 -619
  155. package/dist/theme-3SYJ3UQA.js +0 -14
  156. package/dist/upgrade-YSXCO63I.js +0 -83
  157. package/dist/verify-JUDKTPKZ.js +0 -14
  158. package/dist/web-H2BJXUBZ.js +0 -39
@@ -1,263 +0,0 @@
1
- import {
2
- hookManager
3
- } from "./chunk-NHPDLYEW.js";
4
-
5
- // src/llm/claude.ts
6
- import Anthropic from "@anthropic-ai/sdk";
7
- function createLLMClient(config) {
8
- const options = {
9
- apiKey: config.apiKey
10
- };
11
- if (config.baseURL) {
12
- options.baseURL = config.baseURL;
13
- }
14
- return new Anthropic(options);
15
- }
16
- function buildMessages(history, userPrompt) {
17
- const messages = [];
18
- if (history && history.length > 0) {
19
- for (const msg of history) {
20
- messages.push({
21
- role: msg.role,
22
- content: msg.content
23
- });
24
- }
25
- }
26
- messages.push({ role: "user", content: userPrompt });
27
- return messages;
28
- }
29
- async function triggerToolHook(event, context) {
30
- try {
31
- return await hookManager.trigger(event, context);
32
- } catch {
33
- return { intercepted: false };
34
- }
35
- }
36
- async function callLLM(client, options) {
37
- const {
38
- systemPrompt,
39
- userPrompt,
40
- tools,
41
- model = "claude-sonnet-4-20250514",
42
- maxTokens = 8192,
43
- history,
44
- onText,
45
- onToolCall,
46
- onThinking,
47
- onToolCallDone
48
- } = options;
49
- const toolDefinitions = tools.map((t) => ({
50
- name: t.definition.name,
51
- description: t.definition.description,
52
- input_schema: t.definition.input_schema
53
- }));
54
- const messages = buildMessages(history, userPrompt);
55
- let totalOutput = "";
56
- let currentRoundText = "";
57
- const allToolCalls = [];
58
- let totalInputTokens = 0;
59
- let totalOutputTokens = 0;
60
- let maxIterations = 10;
61
- while (maxIterations-- > 0) {
62
- currentRoundText = "";
63
- const response = await client.messages.create({
64
- model,
65
- max_tokens: maxTokens,
66
- system: systemPrompt,
67
- messages,
68
- tools: toolDefinitions.length > 0 ? toolDefinitions : void 0
69
- });
70
- totalInputTokens += response.usage.input_tokens;
71
- totalOutputTokens += response.usage.output_tokens;
72
- let hasToolUse = false;
73
- let thinkingEmitted = false;
74
- const toolResults = [];
75
- for (const block of response.content) {
76
- if (block.type === "text") {
77
- totalOutput += block.text;
78
- currentRoundText += block.text;
79
- onText?.(block.text);
80
- } else if (block.type === "tool_use") {
81
- hasToolUse = true;
82
- if (!thinkingEmitted && currentRoundText.trim()) {
83
- onThinking?.(currentRoundText.trim());
84
- thinkingEmitted = true;
85
- }
86
- const tool = tools.find((t) => t.definition.name === block.name);
87
- const toolInput = block.input;
88
- const toolInputText = JSON.stringify(toolInput);
89
- onToolCall?.(block.name, toolInput);
90
- let result;
91
- const toolStart = Date.now();
92
- const hookResult = await triggerToolHook("onToolCall", {
93
- model,
94
- toolName: block.name,
95
- toolInput: toolInputText
96
- });
97
- if (hookResult.intercepted) {
98
- result = `Error: Hook intercepted tool call - ${hookResult.reason || "blocked"}`;
99
- } else if (tool) {
100
- try {
101
- result = await tool.handler(toolInput);
102
- } catch (err) {
103
- result = `Error: ${err instanceof Error ? err.message : String(err)}`;
104
- }
105
- } else {
106
- result = `Error: Tool "${block.name}" not found`;
107
- }
108
- const toolDuration = Date.now() - toolStart;
109
- onToolCallDone?.(block.name, toolDuration);
110
- await triggerToolHook("onToolResult", {
111
- model,
112
- toolName: block.name,
113
- toolInput: toolInputText,
114
- toolResult: result
115
- });
116
- allToolCalls.push({
117
- toolName: block.name,
118
- input: toolInput,
119
- output: result
120
- });
121
- toolResults.push({
122
- type: "tool_result",
123
- tool_use_id: block.id,
124
- content: result
125
- });
126
- }
127
- }
128
- if (hasToolUse) {
129
- messages.push({ role: "assistant", content: response.content });
130
- messages.push({ role: "user", content: toolResults });
131
- } else {
132
- break;
133
- }
134
- if (response.stop_reason === "end_turn") break;
135
- }
136
- return {
137
- output: totalOutput,
138
- responseText: allToolCalls.length > 0 ? currentRoundText : totalOutput,
139
- toolCalls: allToolCalls,
140
- tokenUsage: {
141
- inputTokens: totalInputTokens,
142
- outputTokens: totalOutputTokens
143
- }
144
- };
145
- }
146
- async function streamCallLLM(client, options) {
147
- const {
148
- systemPrompt,
149
- userPrompt,
150
- tools,
151
- model = "claude-sonnet-4-20250514",
152
- maxTokens = 8192,
153
- history,
154
- onText,
155
- onToolCall,
156
- onThinking,
157
- onToolCallDone
158
- } = options;
159
- const toolDefinitions = tools.map((t) => ({
160
- name: t.definition.name,
161
- description: t.definition.description,
162
- input_schema: t.definition.input_schema
163
- }));
164
- const messages = buildMessages(history, userPrompt);
165
- let totalOutput = "";
166
- let currentRoundText = "";
167
- const allToolCalls = [];
168
- let totalInputTokens = 0;
169
- let totalOutputTokens = 0;
170
- let maxIterations = 10;
171
- while (maxIterations-- > 0) {
172
- currentRoundText = "";
173
- const stream = client.messages.stream({
174
- model,
175
- max_tokens: maxTokens,
176
- system: systemPrompt,
177
- messages,
178
- tools: toolDefinitions.length > 0 ? toolDefinitions : void 0
179
- });
180
- stream.on("text", (text) => {
181
- totalOutput += text;
182
- currentRoundText += text;
183
- onText?.(text);
184
- });
185
- const response = await stream.finalMessage();
186
- totalInputTokens += response.usage.input_tokens;
187
- totalOutputTokens += response.usage.output_tokens;
188
- let hasToolUse = false;
189
- let thinkingEmitted = false;
190
- const toolResults = [];
191
- for (const block of response.content) {
192
- if (block.type === "tool_use") {
193
- hasToolUse = true;
194
- if (!thinkingEmitted && currentRoundText.trim()) {
195
- onThinking?.(currentRoundText.trim());
196
- thinkingEmitted = true;
197
- }
198
- const toolInput = block.input;
199
- const toolInputText = JSON.stringify(toolInput);
200
- onToolCall?.(block.name, toolInput);
201
- const tool = tools.find((t) => t.definition.name === block.name);
202
- let result;
203
- const toolStart = Date.now();
204
- const hookResult = await triggerToolHook("onToolCall", {
205
- model,
206
- toolName: block.name,
207
- toolInput: toolInputText
208
- });
209
- if (hookResult.intercepted) {
210
- result = `Error: Hook intercepted tool call - ${hookResult.reason || "blocked"}`;
211
- } else if (tool) {
212
- try {
213
- result = await tool.handler(toolInput);
214
- } catch (err) {
215
- result = `Error: ${err instanceof Error ? err.message : String(err)}`;
216
- }
217
- } else {
218
- result = `Error: Tool "${block.name}" not found`;
219
- }
220
- const toolDuration = Date.now() - toolStart;
221
- onToolCallDone?.(block.name, toolDuration);
222
- await triggerToolHook("onToolResult", {
223
- model,
224
- toolName: block.name,
225
- toolInput: toolInputText,
226
- toolResult: result
227
- });
228
- allToolCalls.push({
229
- toolName: block.name,
230
- input: toolInput,
231
- output: result
232
- });
233
- toolResults.push({
234
- type: "tool_result",
235
- tool_use_id: block.id,
236
- content: result
237
- });
238
- }
239
- }
240
- if (hasToolUse) {
241
- messages.push({ role: "assistant", content: response.content });
242
- messages.push({ role: "user", content: toolResults });
243
- } else {
244
- break;
245
- }
246
- if (response.stop_reason === "end_turn") break;
247
- }
248
- return {
249
- output: totalOutput,
250
- responseText: allToolCalls.length > 0 ? currentRoundText : totalOutput,
251
- toolCalls: allToolCalls,
252
- tokenUsage: {
253
- inputTokens: totalInputTokens,
254
- outputTokens: totalOutputTokens
255
- }
256
- };
257
- }
258
-
259
- export {
260
- createLLMClient,
261
- callLLM,
262
- streamCallLLM
263
- };
@@ -1,223 +0,0 @@
1
- import {
2
- displayWidth,
3
- padToWidth,
4
- truncateToWidth
5
- } from "./chunk-BE46C7JW.js";
6
-
7
- // src/ui/markdown.ts
8
- import chalk from "chalk";
9
- import { Marked } from "marked";
10
- import { markedTerminal } from "marked-terminal";
11
- var INDENT = " ";
12
- function renderTable(token) {
13
- const termWidth = process.stdout.columns || 120;
14
- const headers = token.header.map((h) => h.text.trim());
15
- const rows = token.rows.map((r) => r.map((c) => c.text.trim()));
16
- const colCount = headers.length;
17
- const colWidths = headers.map((h) => displayWidth(h));
18
- for (const row of rows) {
19
- for (let i = 0; i < colCount; i++) {
20
- const cellText = row[i] || "";
21
- const w = displayWidth(cellText);
22
- if (w > colWidths[i]) colWidths[i] = w;
23
- }
24
- }
25
- const paddedWidths = colWidths.map((w) => w + 2);
26
- const borderOverhead = colCount + 1;
27
- const totalWidth = paddedWidths.reduce((a, b) => a + b, 0) + borderOverhead;
28
- if (totalWidth > termWidth) {
29
- const available = termWidth - borderOverhead - 4;
30
- const ratio = available / paddedWidths.reduce((a, b) => a + b, 0);
31
- for (let i = 0; i < colCount; i++) {
32
- paddedWidths[i] = Math.max(4, Math.floor(paddedWidths[i] * ratio));
33
- }
34
- }
35
- const contentWidths = paddedWidths.map((w) => w - 2);
36
- const topLine = INDENT + "\u250C" + paddedWidths.map((w) => "\u2500".repeat(w)).join("\u252C") + "\u2510";
37
- const midLine = INDENT + "\u251C" + paddedWidths.map((w) => "\u2500".repeat(w)).join("\u253C") + "\u2524";
38
- const bottomLine = INDENT + "\u2514" + paddedWidths.map((w) => "\u2500".repeat(w)).join("\u2534") + "\u2518";
39
- const headerCells = headers.map((h, i) => {
40
- const text = displayWidth(h) > contentWidths[i] ? truncateToWidth(h, contentWidths[i]) : h;
41
- return " " + padToWidth(text, contentWidths[i]) + " ";
42
- });
43
- const headerRow = INDENT + "\u2502" + headerCells.map((c) => chalk.bold(c)).join("\u2502") + "\u2502";
44
- const dataRows = rows.map((row) => {
45
- const cells = row.map((cell, i) => {
46
- const cellText = cell || "";
47
- const text = displayWidth(cellText) > contentWidths[i] ? truncateToWidth(cellText, contentWidths[i]) : cellText;
48
- return " " + padToWidth(text, contentWidths[i]) + " ";
49
- });
50
- return INDENT + "\u2502" + cells.join("\u2502") + "\u2502";
51
- });
52
- return ["", topLine, headerRow, midLine, ...dataRows, bottomLine, ""].join("\n") + "\n";
53
- }
54
- function highlightCode(code, lang) {
55
- const l = lang.toLowerCase();
56
- if (l === "json" || l === "jsonc") {
57
- return code.replace(/"([^"]*)"(?=\s*:)/g, chalk.cyan('"$1"')).replace(/:\s*"([^"]*)"/g, ": " + chalk.green('"$1"')).replace(/:\s*(\d+\.?\d*)/g, ": " + chalk.yellow("$1")).replace(/:\s*(true|false|null)/g, ": " + chalk.magenta("$1"));
58
- }
59
- if (l === "bash" || l === "sh" || l === "shell" || l === "zsh") {
60
- return code.replace(/(#.*)$/gm, chalk.gray("$1")).replace(/\b(if|then|else|fi|for|do|done|while|case|esac|function|return|export|source|alias|echo|cd|ls|rm|cp|mv|mkdir|chmod|grep|sed|awk|cat|git|npm|node|docker)\b/g, chalk.blue("$1")).replace(/"([^"]*)"/g, chalk.green('"$1"')).replace(/'([^']*)'/g, chalk.green("'$1'")).replace(/\$\w+/g, chalk.cyan("$&"));
61
- }
62
- if (l === "css" || l === "scss" || l === "less") {
63
- return code.replace(/(\/\*[\s\S]*?\*\/)/g, chalk.gray("$1")).replace(/(#[0-9a-fA-F]{3,8})\b/g, chalk.yellow("$1")).replace(/(\d+\.?\d*)(px|em|rem|%|vh|vw|s|ms)/g, chalk.yellow("$1$2")).replace(/\b(var|calc|rgba?|hsla?)\b/g, chalk.blue("$1"));
64
- }
65
- const isJSTS = ["js", "javascript", "ts", "typescript", "jsx", "tsx"].includes(l);
66
- const isPython = ["python", "py"].includes(l);
67
- const isGo = l === "go";
68
- const isRust = l === "rust" || l === "rs";
69
- if (isJSTS || isPython || isGo || isRust || !l) {
70
- let result = code;
71
- result = result.replace(/(\/\/.*)$/gm, chalk.gray("$1"));
72
- result = result.replace(/(#.*)$/gm, chalk.gray("$1"));
73
- result = result.replace(/"([^"\\]*(\\.[^"\\]*)*)"/g, chalk.green('"$1"'));
74
- result = result.replace(/'([^'\\]*(\\.[^'\\]*)*)'/g, chalk.green("'$1'"));
75
- result = result.replace(/`([^`]*)`/g, chalk.green("`$1`"));
76
- let keywords;
77
- if (isJSTS) {
78
- keywords = ["import", "export", "from", "const", "let", "var", "function", "class", "interface", "type", "enum", "return", "if", "else", "for", "while", "switch", "case", "break", "continue", "async", "await", "new", "this", "extends", "implements", "typeof", "instanceof", "default", "try", "catch", "finally", "throw"];
79
- } else if (isPython) {
80
- keywords = ["import", "from", "def", "class", "return", "if", "elif", "else", "for", "while", "try", "except", "finally", "with", "as", "in", "not", "and", "or", "is", "None", "True", "False", "lambda", "yield", "async", "await", "raise", "pass", "self"];
81
- } else if (isGo) {
82
- keywords = ["package", "import", "func", "return", "if", "else", "for", "range", "switch", "case", "default", "var", "const", "type", "struct", "interface", "map", "chan", "go", "defer", "select", "nil", "true", "false"];
83
- } else if (isRust) {
84
- keywords = ["use", "fn", "let", "mut", "const", "struct", "enum", "impl", "trait", "pub", "mod", "return", "if", "else", "for", "while", "loop", "match", "self", "Self", "true", "false", "None", "Some", "Ok", "Err", "async", "await", "move", "where"];
85
- } else {
86
- keywords = ["import", "export", "function", "class", "return", "if", "else", "for", "while", "const", "let", "var"];
87
- }
88
- const kwPattern = new RegExp(`\\b(${keywords.join("|")})\\b`, "g");
89
- result = result.replace(kwPattern, chalk.blue("$1"));
90
- result = result.replace(/\b(\d+\.?\d*)\b/g, chalk.yellow("$1"));
91
- return result;
92
- }
93
- return code;
94
- }
95
- var cjkTableAndCodeExtension = {
96
- renderer: {
97
- // 标题渲染:去除 # 前缀,纯样式输出
98
- heading(token) {
99
- const text = token.text;
100
- if (token.depth === 1) {
101
- return "\n" + chalk.bold.underline(text) + "\n\n";
102
- }
103
- if (token.depth === 2) {
104
- return "\n" + chalk.bold(text) + "\n\n";
105
- }
106
- return "\n" + chalk.bold(text) + "\n\n";
107
- },
108
- table(token) {
109
- return renderTable(token);
110
- },
111
- code(token) {
112
- const lang = token.lang || "";
113
- const highlighted = highlightCode(token.text, lang);
114
- const termW = process.stdout.columns || 80;
115
- const codeW = Math.min(termW - 6, 76);
116
- const langLabel = lang ? chalk.dim.italic(` ${lang}`) : "";
117
- const topBorder = INDENT + chalk.dim("\u250C" + "\u2500".repeat(codeW) + "\u2510") + langLabel;
118
- const botBorder = INDENT + chalk.dim("\u2514" + "\u2500".repeat(codeW) + "\u2518");
119
- const codeLines = highlighted.split("\n").map((line) => {
120
- return INDENT + chalk.dim("\u2502") + chalk.bgHex("#1a1a2e")(" " + line) + " ";
121
- });
122
- return "\n" + topBorder + "\n" + codeLines.join("\n") + "\n" + botBorder + "\n";
123
- }
124
- }
125
- };
126
- var marked = new Marked(
127
- // 先注册 marked-terminal 基础渲染
128
- markedTerminal({
129
- code: chalk.yellow,
130
- codespan: chalk.cyan,
131
- strong: chalk.bold,
132
- em: chalk.italic,
133
- link: chalk.blue.underline,
134
- // 标题:粗体 + 下划线(一级)/ 粗体(其他)
135
- firstHeading: chalk.bold.underline,
136
- heading: chalk.bold,
137
- blockquote: chalk.gray.italic,
138
- listitem: chalk.reset,
139
- // 渲染宽度
140
- width: (process.stdout.columns || 80) - 4
141
- }),
142
- // 后注册自定义扩展(优先级更高)
143
- cjkTableAndCodeExtension
144
- );
145
- function preprocess(text) {
146
- const normalized = normalizeSpacing(text);
147
- return normalized.replace(/^(\s*)\* /gm, "$1- ");
148
- }
149
- function isListLine(line) {
150
- const t = line.trim();
151
- return /^[-+*]\s+/.test(t) || /^\d+\.\s+/.test(t);
152
- }
153
- function normalizeSpacing(text) {
154
- const lines = text.replace(/\r\n/g, "\n").split("\n");
155
- const out = [];
156
- let inCodeFence = false;
157
- let blankCount = 0;
158
- for (let i = 0; i < lines.length; i++) {
159
- const current = lines[i].replace(/\s+$/g, "");
160
- const trimmed = current.trim();
161
- if (/^```/.test(trimmed)) {
162
- inCodeFence = !inCodeFence;
163
- blankCount = 0;
164
- out.push(current);
165
- continue;
166
- }
167
- if (!inCodeFence && trimmed === "") {
168
- const prev = out.length > 0 ? out[out.length - 1] : "";
169
- const next = i + 1 < lines.length ? lines[i + 1].trim() : "";
170
- if (isListLine(prev) && isListLine(next)) {
171
- continue;
172
- }
173
- blankCount += 1;
174
- if (blankCount > 1) continue;
175
- out.push("");
176
- continue;
177
- }
178
- blankCount = 0;
179
- out.push(current);
180
- }
181
- return out.join("\n").trim();
182
- }
183
- function addIndent(rendered) {
184
- const lines = rendered.split("\n");
185
- const out = [];
186
- let prevBlank = false;
187
- for (const line of lines) {
188
- const trimmed = line.trim();
189
- const isBlank = trimmed === "";
190
- if (isBlank) {
191
- if (!prevBlank) out.push("");
192
- prevBlank = true;
193
- continue;
194
- }
195
- prevBlank = false;
196
- if (/^ /.test(line)) {
197
- out.push(line);
198
- } else {
199
- out.push(INDENT + line);
200
- }
201
- }
202
- return out.join("\n");
203
- }
204
- function renderMarkdown(text) {
205
- try {
206
- let rendered = marked.parse(preprocess(text));
207
- rendered = rendered.replace(/^(\s*)(\*) /gm, "$1- ");
208
- rendered = rendered.replace(/\*\*(.+?)\*\*/g, (_m, content) => chalk.bold(content));
209
- rendered = rendered.replace(/(?<!\*)\*([^*\s][^*]*?)\*(?!\*)/g, (_m, content) => chalk.italic(content));
210
- rendered = rendered.replace(/^(\x1b\[0m)+/gm, "");
211
- rendered = rendered.replace(/^\s*(\x1b\[[0-9;]*m\s*)+$/gm, "");
212
- rendered = rendered.replace(/(\x1b\[0m){2,}/g, "\x1B[0m");
213
- rendered = rendered.replace(/\n{3,}/g, "\n\n");
214
- rendered = addIndent(rendered);
215
- return rendered;
216
- } catch {
217
- return text;
218
- }
219
- }
220
-
221
- export {
222
- renderMarkdown
223
- };
@@ -1,134 +0,0 @@
1
- import {
2
- HYPERCORE_DIR
3
- } from "./chunk-SVF2VWOZ.js";
4
-
5
- // src/repl/session.ts
6
- import { mkdir, writeFile, readFile, readdir, rename } from "fs/promises";
7
- import { join } from "path";
8
- import { existsSync } from "fs";
9
- var SESSIONS_DIR = join(HYPERCORE_DIR, "sessions");
10
- function generateSessionId() {
11
- const now = /* @__PURE__ */ new Date();
12
- const date = now.toISOString().split("T")[0];
13
- const time = now.toTimeString().split(" ")[0].replace(/:/g, "");
14
- return `${date}-${time}`;
15
- }
16
- async function saveSession(sessionId, messages, name) {
17
- await mkdir(SESSIONS_DIR, { recursive: true });
18
- const data = {
19
- id: sessionId,
20
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
21
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
22
- messages
23
- };
24
- const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
25
- if (existsSync(filePath)) {
26
- try {
27
- const existing = JSON.parse(await readFile(filePath, "utf-8"));
28
- data.createdAt = existing.createdAt;
29
- if (!name && existing.name) data.name = existing.name;
30
- } catch {
31
- }
32
- }
33
- if (name) data.name = name;
34
- await writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
35
- }
36
- async function loadSession(sessionId) {
37
- const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
38
- if (!existsSync(filePath)) {
39
- throw new Error(`\u4F1A\u8BDD ${sessionId} \u4E0D\u5B58\u5728`);
40
- }
41
- const data = JSON.parse(await readFile(filePath, "utf-8"));
42
- return data.messages;
43
- }
44
- async function listSessions(limit = 10) {
45
- if (!existsSync(SESSIONS_DIR)) return [];
46
- const files = await readdir(SESSIONS_DIR);
47
- const sessions = [];
48
- for (const file of files) {
49
- if (!file.endsWith(".json")) continue;
50
- try {
51
- const data = JSON.parse(await readFile(join(SESSIONS_DIR, file), "utf-8"));
52
- sessions.push({
53
- id: data.id,
54
- name: data.name,
55
- updatedAt: data.updatedAt,
56
- messageCount: data.messages.length
57
- });
58
- } catch {
59
- }
60
- }
61
- sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
62
- return sessions.slice(0, limit);
63
- }
64
- async function renameSession(oldId, newId) {
65
- const oldPath = join(SESSIONS_DIR, `${oldId}.json`);
66
- const newPath = join(SESSIONS_DIR, `${newId}.json`);
67
- if (!existsSync(oldPath)) throw new Error(`\u4F1A\u8BDD ${oldId} \u4E0D\u5B58\u5728`);
68
- if (existsSync(newPath)) throw new Error(`\u4F1A\u8BDD ${newId} \u5DF2\u5B58\u5728`);
69
- const data = JSON.parse(await readFile(oldPath, "utf-8"));
70
- data.id = newId;
71
- data.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
72
- await writeFile(newPath, JSON.stringify(data, null, 2), "utf-8");
73
- await rename(oldPath, join(SESSIONS_DIR, `${oldId}.json.bak`)).catch(() => {
74
- });
75
- const { unlink } = await import("fs/promises");
76
- await unlink(join(SESSIONS_DIR, `${oldId}.json.bak`)).catch(() => {
77
- });
78
- }
79
- async function forkSession(sourceId) {
80
- const sourcePath = join(SESSIONS_DIR, `${sourceId}.json`);
81
- if (!existsSync(sourcePath)) throw new Error(`\u4F1A\u8BDD ${sourceId} \u4E0D\u5B58\u5728`);
82
- const newId = generateSessionId() + "-fork";
83
- const newPath = join(SESSIONS_DIR, `${newId}.json`);
84
- const data = JSON.parse(await readFile(sourcePath, "utf-8"));
85
- data.id = newId;
86
- data.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
87
- await writeFile(newPath, JSON.stringify(data, null, 2), "utf-8");
88
- return newId;
89
- }
90
- async function exportSession(sessionId, outputPath) {
91
- const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
92
- if (!existsSync(filePath)) throw new Error(`\u4F1A\u8BDD ${sessionId} \u4E0D\u5B58\u5728`);
93
- const data = JSON.parse(await readFile(filePath, "utf-8"));
94
- const lines = [
95
- `# \u4F1A\u8BDD: ${data.id}`,
96
- ``,
97
- `- \u521B\u5EFA: ${data.createdAt}`,
98
- `- \u66F4\u65B0: ${data.updatedAt}`,
99
- `- \u6D88\u606F\u6570: ${data.messages.length}`,
100
- ``,
101
- `---`,
102
- ``
103
- ];
104
- for (const msg of data.messages) {
105
- const role = msg.role === "user" ? "\u{1F464} \u7528\u6237" : "\u{1F916} AI";
106
- lines.push(`## ${role}
107
- `);
108
- lines.push(msg.content);
109
- lines.push("");
110
- lines.push("---");
111
- lines.push("");
112
- }
113
- const mdContent = lines.join("\n");
114
- const dest = outputPath || join(process.cwd(), `session-${sessionId}.md`);
115
- await writeFile(dest, mdContent, "utf-8");
116
- return dest;
117
- }
118
- async function deleteSession(sessionId) {
119
- const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
120
- if (!existsSync(filePath)) throw new Error(`\u4F1A\u8BDD ${sessionId} \u4E0D\u5B58\u5728`);
121
- const { unlink } = await import("fs/promises");
122
- await unlink(filePath);
123
- }
124
-
125
- export {
126
- generateSessionId,
127
- saveSession,
128
- loadSession,
129
- listSessions,
130
- renameSession,
131
- forkSession,
132
- exportSession,
133
- deleteSession
134
- };
@@ -1,69 +0,0 @@
1
- // src/core/permissions.ts
2
- import chalk from "chalk";
3
- import { confirm } from "@inquirer/prompts";
4
- var TOOL_PERMISSIONS = {
5
- // safe — 只读操作
6
- file_read: "safe",
7
- glob: "safe",
8
- grep: "safe",
9
- web_fetch: "safe",
10
- web_search: "safe",
11
- memory_search: "safe",
12
- notebook_read: "safe",
13
- task_output: "safe",
14
- sub_agent: "safe",
15
- // write — 文件修改操作
16
- file_write: "write",
17
- file_edit: "write",
18
- memory_save: "write",
19
- notebook_edit: "write",
20
- // dangerous — 系统级操作
21
- bash: "dangerous"
22
- };
23
- function getToolPermission(toolName) {
24
- if (TOOL_PERMISSIONS[toolName]) return TOOL_PERMISSIONS[toolName];
25
- if (toolName.startsWith("mcp_")) return "write";
26
- return "write";
27
- }
28
- function wrapToolWithPermission(tool, config) {
29
- const level = getToolPermission(tool.definition.name);
30
- if (level === "safe") return tool;
31
- const originalHandler = tool.handler;
32
- return {
33
- definition: tool.definition,
34
- handler: async (input) => {
35
- const mode = config.permissionMode || "full";
36
- if (mode === "full") return originalHandler(input);
37
- if (mode === "safe") {
38
- return `\u26D4 \u6743\u9650\u62D2\u7EDD: \u5F53\u524D\u4E3A safe \u6A21\u5F0F\uFF0C\u5DE5\u5177 "${tool.definition.name}" (${level}) \u4E0D\u53EF\u7528\u3002\u4F7F\u7528 /permissions full \u5207\u6362\u6A21\u5F0F\u3002`;
39
- }
40
- if (mode === "ask") {
41
- const inputPreview = JSON.stringify(input).slice(0, 200);
42
- console.log(chalk.yellow(`
43
- \u26A0\uFE0F \u6743\u9650\u786E\u8BA4: ${tool.definition.name} [${level}]`));
44
- console.log(chalk.dim(` \u8F93\u5165: ${inputPreview}`));
45
- try {
46
- const yes = await confirm({
47
- message: `\u5141\u8BB8\u6267\u884C ${tool.definition.name}?`,
48
- default: true
49
- });
50
- if (!yes) {
51
- return `\u26D4 \u7528\u6237\u62D2\u7EDD\u6267\u884C "${tool.definition.name}"`;
52
- }
53
- } catch {
54
- return `\u26D4 \u7528\u6237\u53D6\u6D88\u6267\u884C "${tool.definition.name}"`;
55
- }
56
- }
57
- return originalHandler(input);
58
- }
59
- };
60
- }
61
- function applyPermissions(tools, config) {
62
- return tools.map((t) => wrapToolWithPermission(t, config));
63
- }
64
-
65
- export {
66
- getToolPermission,
67
- wrapToolWithPermission,
68
- applyPermissions
69
- };