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.
- package/LICENSE +92 -21
- package/README.md +8 -1
- package/dist/App-YMX7FSXR.js +1 -0
- package/dist/api-Q2TX5JJL.js +1 -0
- package/dist/auth-X6CUT3DW.js +1 -0
- package/dist/background-ACODXSUG.js +1 -0
- package/dist/backlog-JD2IM336.js +1 -0
- package/dist/chunk-2QI2IU2V.js +1 -0
- package/dist/chunk-3KFRDIPQ.js +1 -0
- package/dist/chunk-42C5J7PN.js +1 -0
- package/dist/chunk-4D7XVJ7Q.js +1 -0
- package/dist/chunk-545IGTXV.js +1 -0
- package/dist/chunk-5KUSGQP2.js +1 -0
- package/dist/chunk-AUQ64BK2.js +1 -0
- package/dist/chunk-AV244H5C.js +1 -0
- package/dist/chunk-BQVBEFS4.js +1 -0
- package/dist/chunk-BYWQLFP2.js +1 -0
- package/dist/chunk-COITWWZJ.js +1 -0
- package/dist/chunk-CR7UUJVX.js +1 -0
- package/dist/chunk-E3MULLBX.js +1 -0
- package/dist/chunk-EWBV7YPP.js +1 -0
- package/dist/chunk-EZHYVJGQ.js +1 -0
- package/dist/chunk-FAKXBY7Q.js +1 -0
- package/dist/chunk-FHGATV5B.js +1 -0
- package/dist/chunk-I2G27Y5P.js +1 -0
- package/dist/chunk-IKF43TX2.js +1 -0
- package/dist/chunk-INSPHCBN.js +1 -0
- package/dist/chunk-LQMDUKIE.js +1 -0
- package/dist/chunk-M3MTKGA5.js +1 -0
- package/dist/chunk-MPO54FU3.js +1 -0
- package/dist/chunk-PVKCZI6A.js +1 -0
- package/dist/chunk-Q7KEPCYL.js +1 -0
- package/dist/chunk-R5XD3NT2.js +1 -0
- package/dist/chunk-ROBZ6PAL.js +1 -0
- package/dist/chunk-RXB5BS2N.js +1 -0
- package/dist/chunk-RZ3HNYMT.js +1 -0
- package/dist/chunk-UCGLRMTG.js +1 -0
- package/dist/chunk-UEHJVRKB.js +1 -0
- package/dist/chunk-UZYX5GGF.js +1 -0
- package/dist/chunk-XQJBB725.js +1 -0
- package/dist/chunk-ZB5ZQSXH.js +1 -0
- package/dist/claude-US2QPRBA.js +1 -0
- package/dist/commands-5TFN74MD.js +1 -0
- package/dist/commands-EKPWCB3T.js +1 -0
- package/dist/commands-QHJLREPM.js +1 -0
- package/dist/config-2OUL5FLS.js +1 -0
- package/dist/config-loader-N7IBWN2P.js +1 -0
- package/dist/diagnose-NLHN4SAJ.js +1 -0
- package/dist/display-TB5YACJV.js +1 -0
- package/dist/extractor-3KTM2IUL.js +1 -0
- package/dist/feature-flag-VVIF5FJG.js +1 -0
- package/dist/history-GVNDPXXQ.js +1 -0
- package/dist/index.js +1 -402
- package/dist/instance-registry-I5AIVJE2.js +1 -0
- package/dist/keybindings-RN3A7CRW.js +1 -0
- package/dist/loader-3IKPXP4R.js +1 -0
- package/dist/network-GI2F3IDE.js +1 -0
- package/dist/notify-O6FNVHC4.js +1 -0
- package/dist/openai-compat-IPCMINVF.js +1 -0
- package/dist/permissions-5O7KVAXU.js +1 -0
- package/dist/prompt-VWFPFM4N.js +1 -0
- package/dist/quality-GPQD25UL.js +1 -0
- package/dist/repl-YNXCDVU4.js +1 -0
- package/dist/roadmap-QRZODSNJ.js +1 -0
- package/dist/server-USQP4GC4.js +1 -0
- package/dist/session-5HDDQQP6.js +1 -0
- package/dist/skills-DXWSVJSU.js +1 -0
- package/dist/store-WXXTKTTL.js +1 -0
- package/dist/team-VTPJ3WRT.js +1 -0
- package/dist/telemetry-NT4UZLBS.js +1 -0
- package/dist/test-runner-F6B6RH3S.js +1 -0
- package/dist/theme-JJJ6ABR2.js +1 -0
- package/dist/upgrade-RUG3R7R5.js +1 -0
- package/dist/verify-6OGRY2PR.js +1 -0
- package/dist/version-DLROA5JN.js +1 -0
- package/dist/web/static/app.js +1 -562
- package/dist/web/static/index.html +114 -126
- package/dist/web/static/mirror.css +1 -1001
- package/dist/web/static/mirror.html +155 -178
- package/dist/web/static/mirror.js +1 -1125
- package/dist/web/static/onboard.css +1 -302
- package/dist/web/static/onboard.html +121 -145
- package/dist/web/static/onboard.js +1 -300
- package/dist/web/static/style.css +1 -602
- package/dist/web/static/utils.js +1 -0
- package/dist/web/static/workspace.css +1 -1568
- package/dist/web/static/workspace.html +369 -402
- package/dist/web/static/workspace.js +1 -1683
- package/dist/web-P5YUKEAU.js +1 -0
- package/package.json +25 -4
- package/dist/api-D4PUN5BN.js +0 -162
- package/dist/auth-UTR4I6QY.js +0 -21
- package/dist/background-2EGCAAQH.js +0 -14
- package/dist/backlog-Q2NZCLNY.js +0 -24
- package/dist/chunk-2CMSCWQW.js +0 -162
- package/dist/chunk-4DVYJAJL.js +0 -57
- package/dist/chunk-77FRUHTU.js +0 -271
- package/dist/chunk-7ZYMJFCA.js +0 -251
- package/dist/chunk-BE46C7JW.js +0 -46
- package/dist/chunk-CM423E2U.js +0 -133
- package/dist/chunk-E4NKO2KI.js +0 -263
- package/dist/chunk-GH7E2OJE.js +0 -223
- package/dist/chunk-GMLQ7GZ5.js +0 -134
- package/dist/chunk-GU2FZQ6A.js +0 -69
- package/dist/chunk-IOPKN5GD.js +0 -190
- package/dist/chunk-LWDNLX6B.js +0 -2025
- package/dist/chunk-MGLJ53QN.js +0 -219
- package/dist/chunk-NHPDLYEW.js +0 -139
- package/dist/chunk-OGQGKMDX.js +0 -173
- package/dist/chunk-OPZYEVYR.js +0 -150
- package/dist/chunk-OWAOKDIN.js +0 -1505
- package/dist/chunk-R3GPQC7I.js +0 -393
- package/dist/chunk-RKB2JOV2.js +0 -43
- package/dist/chunk-RNG3K465.js +0 -80
- package/dist/chunk-SHJQMIJL.js +0 -288
- package/dist/chunk-SVF2VWOZ.js +0 -145
- package/dist/chunk-TGTYKBGC.js +0 -86
- package/dist/chunk-V2EBSFPU.js +0 -575
- package/dist/chunk-VJDQNNSO.js +0 -681
- package/dist/chunk-VQ35XX7B.js +0 -167
- package/dist/chunk-WHLVZCQY.js +0 -245
- package/dist/chunk-XMGHVNH2.js +0 -66
- package/dist/chunk-YWOSOTUO.js +0 -58
- package/dist/chunk-ZQRNV2US.js +0 -166
- package/dist/chunk-ZSBHUGWR.js +0 -262
- package/dist/claude-O5FSOXZC.js +0 -12
- package/dist/commands-43PLOWRU.js +0 -128
- package/dist/commands-5YVUSUMP.js +0 -232
- package/dist/commands-VZMZJFZF.js +0 -1044
- package/dist/config-WXXEEEVW.js +0 -8
- package/dist/config-loader-SXO674TF.js +0 -24
- package/dist/diagnose-BX45APUZ.js +0 -12
- package/dist/display-IIUBEYWN.js +0 -58
- package/dist/extractor-R5ABXNTJ.js +0 -129
- package/dist/history-JPXZEOT3.js +0 -180
- package/dist/index.d.ts +0 -1
- package/dist/instance-registry-6NJTCAE4.js +0 -15
- package/dist/keybindings-ADWNOX5M.js +0 -15
- package/dist/loader-AXDDCB2G.js +0 -58
- package/dist/network-V3O4UZYZ.js +0 -279
- package/dist/notify-HPTALZDC.js +0 -14
- package/dist/openai-compat-UFDV2SCK.js +0 -12
- package/dist/permissions-JUKXMNDH.js +0 -10
- package/dist/prompt-5CZ34WGA.js +0 -166
- package/dist/quality-ST7PPNFR.js +0 -16
- package/dist/repl-EOWP6AAB.js +0 -3374
- package/dist/roadmap-5OBEKROY.js +0 -17
- package/dist/server-BB5AENWU.js +0 -57
- package/dist/session-5NDKKFLN.js +0 -21
- package/dist/skills-JVLIQVJN.js +0 -175
- package/dist/store-G7KRD4PN.js +0 -25
- package/dist/team-FVNNVDBY.js +0 -385
- package/dist/telemetry-6R4EIE6O.js +0 -30
- package/dist/test-runner-REKSVPPY.js +0 -619
- package/dist/theme-3SYJ3UQA.js +0 -14
- package/dist/upgrade-YSXCO63I.js +0 -83
- package/dist/verify-JUDKTPKZ.js +0 -14
- package/dist/web-H2BJXUBZ.js +0 -39
package/dist/chunk-77FRUHTU.js
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
hookManager
|
|
3
|
-
} from "./chunk-NHPDLYEW.js";
|
|
4
|
-
|
|
5
|
-
// src/llm/openai-compat.ts
|
|
6
|
-
import OpenAI from "openai";
|
|
7
|
-
function createOpenAIClient(config) {
|
|
8
|
-
return new OpenAI({
|
|
9
|
-
apiKey: config.apiKey,
|
|
10
|
-
baseURL: config.baseURL
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
async function triggerToolHook(event, context) {
|
|
14
|
-
try {
|
|
15
|
-
return await hookManager.trigger(event, context);
|
|
16
|
-
} catch {
|
|
17
|
-
return { intercepted: false };
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
async function callOpenAILLM(client, options) {
|
|
21
|
-
const {
|
|
22
|
-
systemPrompt,
|
|
23
|
-
userPrompt,
|
|
24
|
-
tools,
|
|
25
|
-
model = "gemini-2.5-flash",
|
|
26
|
-
maxTokens = 8192,
|
|
27
|
-
onText,
|
|
28
|
-
onToolCall,
|
|
29
|
-
onThinking,
|
|
30
|
-
onToolCallDone
|
|
31
|
-
} = options;
|
|
32
|
-
const toolDefinitions = tools.map((t) => ({
|
|
33
|
-
type: "function",
|
|
34
|
-
function: {
|
|
35
|
-
name: t.definition.name,
|
|
36
|
-
description: t.definition.description,
|
|
37
|
-
parameters: t.definition.input_schema
|
|
38
|
-
}
|
|
39
|
-
}));
|
|
40
|
-
const messages = [
|
|
41
|
-
{ role: "system", content: systemPrompt },
|
|
42
|
-
{ role: "user", content: userPrompt }
|
|
43
|
-
];
|
|
44
|
-
let totalOutput = "";
|
|
45
|
-
let currentRoundText = "";
|
|
46
|
-
const allToolCalls = [];
|
|
47
|
-
let totalInputTokens = 0;
|
|
48
|
-
let totalOutputTokens = 0;
|
|
49
|
-
let maxIterations = 10;
|
|
50
|
-
while (maxIterations-- > 0) {
|
|
51
|
-
currentRoundText = "";
|
|
52
|
-
const response = await client.chat.completions.create({
|
|
53
|
-
model,
|
|
54
|
-
max_tokens: maxTokens,
|
|
55
|
-
messages,
|
|
56
|
-
tools: toolDefinitions.length > 0 ? toolDefinitions : void 0
|
|
57
|
-
});
|
|
58
|
-
if (response.usage) {
|
|
59
|
-
totalInputTokens += response.usage.prompt_tokens || 0;
|
|
60
|
-
totalOutputTokens += response.usage.completion_tokens || 0;
|
|
61
|
-
}
|
|
62
|
-
const choice = response.choices[0];
|
|
63
|
-
if (!choice) break;
|
|
64
|
-
const message = choice.message;
|
|
65
|
-
if (message.content) {
|
|
66
|
-
totalOutput += message.content;
|
|
67
|
-
currentRoundText += message.content;
|
|
68
|
-
onText?.(message.content);
|
|
69
|
-
}
|
|
70
|
-
if (message.tool_calls && message.tool_calls.length > 0) {
|
|
71
|
-
if (currentRoundText.trim()) {
|
|
72
|
-
onThinking?.(currentRoundText.trim());
|
|
73
|
-
}
|
|
74
|
-
messages.push(message);
|
|
75
|
-
for (const toolCall of message.tool_calls) {
|
|
76
|
-
const fn = toolCall.function;
|
|
77
|
-
const fnName = fn.name;
|
|
78
|
-
let fnArgs = {};
|
|
79
|
-
try {
|
|
80
|
-
fnArgs = JSON.parse(fn.arguments || "{}");
|
|
81
|
-
} catch {
|
|
82
|
-
}
|
|
83
|
-
const toolInputText = JSON.stringify(fnArgs);
|
|
84
|
-
onToolCall?.(fnName, fnArgs);
|
|
85
|
-
const tool = tools.find((t) => t.definition.name === fnName);
|
|
86
|
-
let result;
|
|
87
|
-
const toolStart = Date.now();
|
|
88
|
-
const hookResult = await triggerToolHook("onToolCall", {
|
|
89
|
-
model,
|
|
90
|
-
toolName: fnName,
|
|
91
|
-
toolInput: toolInputText
|
|
92
|
-
});
|
|
93
|
-
if (hookResult.intercepted) {
|
|
94
|
-
result = `Error: Hook intercepted tool call - ${hookResult.reason || "blocked"}`;
|
|
95
|
-
} else if (tool) {
|
|
96
|
-
try {
|
|
97
|
-
result = await tool.handler(fnArgs);
|
|
98
|
-
} catch (err) {
|
|
99
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
result = `Error: Tool "${fnName}" not found`;
|
|
103
|
-
}
|
|
104
|
-
const toolDuration = Date.now() - toolStart;
|
|
105
|
-
onToolCallDone?.(fnName, toolDuration);
|
|
106
|
-
await triggerToolHook("onToolResult", {
|
|
107
|
-
model,
|
|
108
|
-
toolName: fnName,
|
|
109
|
-
toolInput: toolInputText,
|
|
110
|
-
toolResult: result
|
|
111
|
-
});
|
|
112
|
-
allToolCalls.push({
|
|
113
|
-
toolName: fnName,
|
|
114
|
-
input: fnArgs,
|
|
115
|
-
output: result
|
|
116
|
-
});
|
|
117
|
-
messages.push({
|
|
118
|
-
role: "tool",
|
|
119
|
-
tool_call_id: toolCall.id,
|
|
120
|
-
content: result
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
return {
|
|
128
|
-
output: totalOutput,
|
|
129
|
-
responseText: allToolCalls.length > 0 ? currentRoundText : totalOutput,
|
|
130
|
-
toolCalls: allToolCalls,
|
|
131
|
-
tokenUsage: {
|
|
132
|
-
inputTokens: totalInputTokens,
|
|
133
|
-
outputTokens: totalOutputTokens
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
async function streamOpenAIChat(client, messages, options) {
|
|
138
|
-
const { model, tools = [], onChunk, onToolCall, onThinking, onToolCallDone } = options;
|
|
139
|
-
const toolDefinitions = tools.map((t) => ({
|
|
140
|
-
type: "function",
|
|
141
|
-
function: {
|
|
142
|
-
name: t.definition.name,
|
|
143
|
-
description: t.definition.description,
|
|
144
|
-
parameters: t.definition.input_schema
|
|
145
|
-
}
|
|
146
|
-
}));
|
|
147
|
-
let totalContent = "";
|
|
148
|
-
let currentRoundContent = "";
|
|
149
|
-
let hasCalledTools = false;
|
|
150
|
-
let totalInputTokens = 0;
|
|
151
|
-
let totalOutputTokens = 0;
|
|
152
|
-
let maxIterations = 10;
|
|
153
|
-
while (maxIterations-- > 0) {
|
|
154
|
-
currentRoundContent = "";
|
|
155
|
-
let stream;
|
|
156
|
-
let lastError;
|
|
157
|
-
for (let retry = 0; retry < 5; retry++) {
|
|
158
|
-
try {
|
|
159
|
-
stream = await client.chat.completions.create({
|
|
160
|
-
model,
|
|
161
|
-
max_tokens: 4096,
|
|
162
|
-
messages,
|
|
163
|
-
tools: toolDefinitions.length > 0 ? toolDefinitions : void 0,
|
|
164
|
-
stream: true
|
|
165
|
-
});
|
|
166
|
-
lastError = null;
|
|
167
|
-
break;
|
|
168
|
-
} catch (err) {
|
|
169
|
-
lastError = err;
|
|
170
|
-
const status = err.status;
|
|
171
|
-
if (status === 429) {
|
|
172
|
-
const wait = (retry + 1) * 5e3;
|
|
173
|
-
process.stdout.write(`\x1B[2m \u23F3 API \u9650\u6D41\uFF0C${wait / 1e3}s \u540E\u91CD\u8BD5...\x1B[0m
|
|
174
|
-
`);
|
|
175
|
-
await new Promise((r) => setTimeout(r, wait));
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
throw err;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
if (lastError) throw lastError;
|
|
182
|
-
let chunkContent = "";
|
|
183
|
-
const toolCalls = /* @__PURE__ */ new Map();
|
|
184
|
-
for await (const chunk of stream) {
|
|
185
|
-
const delta = chunk.choices[0]?.delta;
|
|
186
|
-
if (!delta) continue;
|
|
187
|
-
if (delta.content) {
|
|
188
|
-
chunkContent += delta.content;
|
|
189
|
-
totalContent += delta.content;
|
|
190
|
-
currentRoundContent += delta.content;
|
|
191
|
-
onChunk?.(delta.content);
|
|
192
|
-
}
|
|
193
|
-
if (delta.tool_calls) {
|
|
194
|
-
for (const tc of delta.tool_calls) {
|
|
195
|
-
const existing = toolCalls.get(tc.index) || { id: "", name: "", args: "" };
|
|
196
|
-
if (tc.id) existing.id = tc.id;
|
|
197
|
-
if (tc.function?.name) existing.name = tc.function.name;
|
|
198
|
-
if (tc.function?.arguments) existing.args += tc.function.arguments;
|
|
199
|
-
toolCalls.set(tc.index, existing);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
if (chunk.usage) {
|
|
203
|
-
totalInputTokens += chunk.usage.prompt_tokens || 0;
|
|
204
|
-
totalOutputTokens += chunk.usage.completion_tokens || 0;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (toolCalls.size === 0) break;
|
|
208
|
-
hasCalledTools = true;
|
|
209
|
-
if (chunkContent.trim()) {
|
|
210
|
-
onThinking?.(chunkContent.trim());
|
|
211
|
-
}
|
|
212
|
-
const assistantMessage = {
|
|
213
|
-
role: "assistant",
|
|
214
|
-
content: chunkContent || null,
|
|
215
|
-
tool_calls: Array.from(toolCalls.values()).map((tc) => ({
|
|
216
|
-
id: tc.id,
|
|
217
|
-
type: "function",
|
|
218
|
-
function: { name: tc.name, arguments: tc.args }
|
|
219
|
-
}))
|
|
220
|
-
};
|
|
221
|
-
messages.push(assistantMessage);
|
|
222
|
-
for (const [, tc] of toolCalls) {
|
|
223
|
-
let fnArgs = {};
|
|
224
|
-
try {
|
|
225
|
-
fnArgs = JSON.parse(tc.args || "{}");
|
|
226
|
-
} catch {
|
|
227
|
-
}
|
|
228
|
-
onToolCall?.(tc.name, fnArgs);
|
|
229
|
-
const toolInputText = JSON.stringify(fnArgs);
|
|
230
|
-
const tool = tools.find((t) => t.definition.name === tc.name);
|
|
231
|
-
let result;
|
|
232
|
-
const toolStart = Date.now();
|
|
233
|
-
const hookResult = await triggerToolHook("onToolCall", {
|
|
234
|
-
model,
|
|
235
|
-
toolName: tc.name,
|
|
236
|
-
toolInput: toolInputText
|
|
237
|
-
});
|
|
238
|
-
if (hookResult.intercepted) {
|
|
239
|
-
result = `Error: Hook intercepted tool call - ${hookResult.reason || "blocked"}`;
|
|
240
|
-
} else if (tool) {
|
|
241
|
-
try {
|
|
242
|
-
result = await tool.handler(fnArgs);
|
|
243
|
-
} catch (err) {
|
|
244
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
245
|
-
}
|
|
246
|
-
} else {
|
|
247
|
-
result = `Error: Tool "${tc.name}" not found`;
|
|
248
|
-
}
|
|
249
|
-
const toolDuration = Date.now() - toolStart;
|
|
250
|
-
onToolCallDone?.(tc.name, toolDuration);
|
|
251
|
-
await triggerToolHook("onToolResult", {
|
|
252
|
-
model,
|
|
253
|
-
toolName: tc.name,
|
|
254
|
-
toolInput: toolInputText,
|
|
255
|
-
toolResult: result
|
|
256
|
-
});
|
|
257
|
-
messages.push({ role: "tool", tool_call_id: tc.id, content: result });
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return {
|
|
261
|
-
content: totalContent,
|
|
262
|
-
responseContent: hasCalledTools ? currentRoundContent : totalContent,
|
|
263
|
-
tokenUsage: { inputTokens: totalInputTokens, outputTokens: totalOutputTokens }
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
export {
|
|
268
|
-
createOpenAIClient,
|
|
269
|
-
callOpenAILLM,
|
|
270
|
-
streamOpenAIChat
|
|
271
|
-
};
|
package/dist/chunk-7ZYMJFCA.js
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HYPERCORE_DIR
|
|
3
|
-
} from "./chunk-SVF2VWOZ.js";
|
|
4
|
-
|
|
5
|
-
// src/memory/store.ts
|
|
6
|
-
import { randomBytes } from "crypto";
|
|
7
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
8
|
-
import { existsSync } from "fs";
|
|
9
|
-
import { join } from "path";
|
|
10
|
-
|
|
11
|
-
// src/memory/types.ts
|
|
12
|
-
var DEFAULT_EXTRACTION_CONFIG = {
|
|
13
|
-
extractEveryNRounds: 3,
|
|
14
|
-
maxMemoriesPerExtraction: 5,
|
|
15
|
-
minConfidence: 0.6,
|
|
16
|
-
maxPersonalMemories: 100,
|
|
17
|
-
maxProjectMemories: 150,
|
|
18
|
-
maxSystemPromptChars: 3e3
|
|
19
|
-
};
|
|
20
|
-
function createEmptyStore(layer) {
|
|
21
|
-
return {
|
|
22
|
-
version: "1",
|
|
23
|
-
layer,
|
|
24
|
-
records: [],
|
|
25
|
-
totalExtractions: 0,
|
|
26
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
var CATEGORY_LABELS = {
|
|
30
|
-
preference: "\u504F\u597D",
|
|
31
|
-
decision: "\u51B3\u7B56",
|
|
32
|
-
entity: "\u5B9E\u4F53",
|
|
33
|
-
pattern: "\u6A21\u5F0F",
|
|
34
|
-
fact: "\u4E8B\u5B9E",
|
|
35
|
-
convention: "\u7EA6\u5B9A",
|
|
36
|
-
insight: "\u6D1E\u5BDF",
|
|
37
|
-
manual: "\u624B\u52A8"
|
|
38
|
-
};
|
|
39
|
-
var CATEGORY_MD_HEADERS = {
|
|
40
|
-
preference: "User Preferences",
|
|
41
|
-
decision: "Key Decisions",
|
|
42
|
-
entity: "Named Entities",
|
|
43
|
-
pattern: "Patterns & Solutions",
|
|
44
|
-
fact: "Known Facts",
|
|
45
|
-
convention: "Conventions",
|
|
46
|
-
insight: "Team Insights",
|
|
47
|
-
manual: "User Notes"
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// src/memory/store.ts
|
|
51
|
-
function memoryDir(layer, opts) {
|
|
52
|
-
switch (layer) {
|
|
53
|
-
case "personal":
|
|
54
|
-
return join(HYPERCORE_DIR, "memory");
|
|
55
|
-
case "project":
|
|
56
|
-
return join(opts?.projectPath || process.cwd(), ".hypercore", "memory");
|
|
57
|
-
case "team":
|
|
58
|
-
if (!opts?.teamId) throw new Error("team layer requires teamId");
|
|
59
|
-
return join(HYPERCORE_DIR, "teams", opts.teamId, "memory");
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function jsonPath(layer, opts) {
|
|
63
|
-
return join(memoryDir(layer, opts), `${layer}.json`);
|
|
64
|
-
}
|
|
65
|
-
function mdPath(layer, opts) {
|
|
66
|
-
return join(memoryDir(layer, opts), `${layer}.md`);
|
|
67
|
-
}
|
|
68
|
-
function generateMemoryId() {
|
|
69
|
-
const ts = Date.now();
|
|
70
|
-
const rand = randomBytes(2).toString("hex");
|
|
71
|
-
return `mem_${ts}_${rand}`;
|
|
72
|
-
}
|
|
73
|
-
async function loadStore(layer, opts) {
|
|
74
|
-
const fp = jsonPath(layer, opts);
|
|
75
|
-
if (!existsSync(fp)) return createEmptyStore(layer);
|
|
76
|
-
try {
|
|
77
|
-
const raw = await readFile(fp, "utf-8");
|
|
78
|
-
return JSON.parse(raw);
|
|
79
|
-
} catch {
|
|
80
|
-
return createEmptyStore(layer);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async function saveStore(store, opts) {
|
|
84
|
-
const dir = memoryDir(store.layer, opts);
|
|
85
|
-
await mkdir(dir, { recursive: true });
|
|
86
|
-
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
87
|
-
await writeFile(jsonPath(store.layer, opts), JSON.stringify(store, null, 2), "utf-8");
|
|
88
|
-
await rebuildMarkdown(store, opts);
|
|
89
|
-
}
|
|
90
|
-
async function addMemory(layer, record, opts) {
|
|
91
|
-
const store = await loadStore(layer, opts);
|
|
92
|
-
const config = DEFAULT_EXTRACTION_CONFIG;
|
|
93
|
-
const maxRecords = layer === "personal" ? config.maxPersonalMemories : config.maxProjectMemories;
|
|
94
|
-
const existingIdx = findDuplicate(store.records, record.content);
|
|
95
|
-
if (existingIdx >= 0) {
|
|
96
|
-
const existing = store.records[existingIdx];
|
|
97
|
-
existing.content = record.content;
|
|
98
|
-
existing.tags = record.tags;
|
|
99
|
-
existing.confidence = Math.max(existing.confidence, record.confidence);
|
|
100
|
-
existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
101
|
-
existing.accessCount++;
|
|
102
|
-
await saveStore(store, opts);
|
|
103
|
-
return existing;
|
|
104
|
-
}
|
|
105
|
-
if (store.records.length >= maxRecords) {
|
|
106
|
-
store.records.sort((a, b) => a.confidence - b.confidence || a.updatedAt.localeCompare(b.updatedAt));
|
|
107
|
-
store.records.shift();
|
|
108
|
-
}
|
|
109
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
110
|
-
const newRecord = {
|
|
111
|
-
...record,
|
|
112
|
-
id: generateMemoryId(),
|
|
113
|
-
layer,
|
|
114
|
-
createdAt: now,
|
|
115
|
-
updatedAt: now,
|
|
116
|
-
accessCount: 0
|
|
117
|
-
};
|
|
118
|
-
store.records.push(newRecord);
|
|
119
|
-
await saveStore(store, opts);
|
|
120
|
-
return newRecord;
|
|
121
|
-
}
|
|
122
|
-
async function removeMemory(layer, memoryId, opts) {
|
|
123
|
-
const store = await loadStore(layer, opts);
|
|
124
|
-
const idx = store.records.findIndex((r) => r.id === memoryId);
|
|
125
|
-
if (idx < 0) return false;
|
|
126
|
-
store.records.splice(idx, 1);
|
|
127
|
-
await saveStore(store, opts);
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
130
|
-
async function searchMemories(layer, query, opts) {
|
|
131
|
-
const store = await loadStore(layer, opts);
|
|
132
|
-
let records = store.records;
|
|
133
|
-
if (opts?.category) {
|
|
134
|
-
records = records.filter((r) => r.category === opts.category);
|
|
135
|
-
}
|
|
136
|
-
const queryLower = query.toLowerCase();
|
|
137
|
-
const queryTerms = queryLower.split(/\s+/).filter(Boolean);
|
|
138
|
-
const scored = records.map((record) => {
|
|
139
|
-
const contentLower = record.content.toLowerCase();
|
|
140
|
-
const tagsLower = record.tags.join(" ").toLowerCase();
|
|
141
|
-
const combined = contentLower + " " + tagsLower;
|
|
142
|
-
let matchedTerms = 0;
|
|
143
|
-
for (const term of queryTerms) {
|
|
144
|
-
if (combined.includes(term)) matchedTerms++;
|
|
145
|
-
}
|
|
146
|
-
const score = queryTerms.length > 0 ? matchedTerms / queryTerms.length : 0;
|
|
147
|
-
return { record, score };
|
|
148
|
-
});
|
|
149
|
-
const results = scored.filter((r) => r.score > 0).sort((a, b) => b.score - a.score || b.record.confidence - a.record.confidence);
|
|
150
|
-
for (const r of results) {
|
|
151
|
-
r.record.accessCount++;
|
|
152
|
-
r.record.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
153
|
-
}
|
|
154
|
-
if (results.length > 0) {
|
|
155
|
-
await saveStore(store, opts);
|
|
156
|
-
}
|
|
157
|
-
return results.slice(0, opts?.limit || 20);
|
|
158
|
-
}
|
|
159
|
-
async function listMemories(layer, opts) {
|
|
160
|
-
const store = await loadStore(layer, opts);
|
|
161
|
-
return [...store.records].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
162
|
-
}
|
|
163
|
-
async function getMemoryStats(layer, opts) {
|
|
164
|
-
const store = await loadStore(layer, opts);
|
|
165
|
-
const byCategory = {};
|
|
166
|
-
for (const r of store.records) {
|
|
167
|
-
byCategory[r.category] = (byCategory[r.category] || 0) + 1;
|
|
168
|
-
}
|
|
169
|
-
return {
|
|
170
|
-
total: store.records.length,
|
|
171
|
-
byCategory,
|
|
172
|
-
lastExtractionAt: store.lastExtractionAt,
|
|
173
|
-
totalExtractions: store.totalExtractions
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
async function markExtraction(layer, opts) {
|
|
177
|
-
const store = await loadStore(layer, opts);
|
|
178
|
-
store.lastExtractionAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
179
|
-
store.totalExtractions++;
|
|
180
|
-
await saveStore(store, opts);
|
|
181
|
-
}
|
|
182
|
-
function findDuplicate(records, content) {
|
|
183
|
-
const normalized = content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
184
|
-
for (let i = 0; i < records.length; i++) {
|
|
185
|
-
const existing = records[i].content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
186
|
-
if (similarityRatio(existing, normalized) > 0.8) return i;
|
|
187
|
-
}
|
|
188
|
-
return -1;
|
|
189
|
-
}
|
|
190
|
-
function similarityRatio(a, b) {
|
|
191
|
-
if (a === b) return 1;
|
|
192
|
-
if (!a || !b) return 0;
|
|
193
|
-
const bigramsA = /* @__PURE__ */ new Set();
|
|
194
|
-
for (let i = 0; i < a.length - 1; i++) bigramsA.add(a.slice(i, i + 2));
|
|
195
|
-
const bigramsB = /* @__PURE__ */ new Set();
|
|
196
|
-
for (let i = 0; i < b.length - 1; i++) bigramsB.add(b.slice(i, i + 2));
|
|
197
|
-
let intersection = 0;
|
|
198
|
-
for (const bg of bigramsA) {
|
|
199
|
-
if (bigramsB.has(bg)) intersection++;
|
|
200
|
-
}
|
|
201
|
-
const union = bigramsA.size + bigramsB.size - intersection;
|
|
202
|
-
return union > 0 ? intersection / union : 0;
|
|
203
|
-
}
|
|
204
|
-
async function rebuildMarkdown(store, opts) {
|
|
205
|
-
const lines = [
|
|
206
|
-
`--- Memory Context (${store.layer}) ---`,
|
|
207
|
-
""
|
|
208
|
-
];
|
|
209
|
-
const grouped = {};
|
|
210
|
-
for (const r of store.records) {
|
|
211
|
-
if (!grouped[r.category]) grouped[r.category] = [];
|
|
212
|
-
grouped[r.category].push(r);
|
|
213
|
-
}
|
|
214
|
-
for (const [category, records] of Object.entries(grouped)) {
|
|
215
|
-
const header = CATEGORY_MD_HEADERS[category] || category;
|
|
216
|
-
lines.push(`[${header}]`);
|
|
217
|
-
const sorted = records.sort((a, b) => b.confidence - a.confidence);
|
|
218
|
-
for (const r of sorted) {
|
|
219
|
-
const tags = r.tags.map((t) => `#${t}`).join(" ");
|
|
220
|
-
lines.push(`- ${r.content} ${tags}`);
|
|
221
|
-
}
|
|
222
|
-
lines.push("");
|
|
223
|
-
}
|
|
224
|
-
lines.push(`--- End Memory Context ---`);
|
|
225
|
-
const fp = mdPath(store.layer, opts);
|
|
226
|
-
await writeFile(fp, lines.join("\n"), "utf-8");
|
|
227
|
-
}
|
|
228
|
-
async function readMemoryMarkdown(layer, opts) {
|
|
229
|
-
const fp = mdPath(layer, opts);
|
|
230
|
-
if (!existsSync(fp)) return "";
|
|
231
|
-
try {
|
|
232
|
-
return await readFile(fp, "utf-8");
|
|
233
|
-
} catch {
|
|
234
|
-
return "";
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export {
|
|
239
|
-
DEFAULT_EXTRACTION_CONFIG,
|
|
240
|
-
CATEGORY_LABELS,
|
|
241
|
-
generateMemoryId,
|
|
242
|
-
loadStore,
|
|
243
|
-
saveStore,
|
|
244
|
-
addMemory,
|
|
245
|
-
removeMemory,
|
|
246
|
-
searchMemories,
|
|
247
|
-
listMemories,
|
|
248
|
-
getMemoryStats,
|
|
249
|
-
markExtraction,
|
|
250
|
-
readMemoryMarkdown
|
|
251
|
-
};
|
package/dist/chunk-BE46C7JW.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// src/ui/text-utils.ts
|
|
2
|
-
function isCJK(char) {
|
|
3
|
-
const code = char.codePointAt(0);
|
|
4
|
-
if (!code) return false;
|
|
5
|
-
return code >= 11904 && code <= 40959 || // CJK 部首/汉字
|
|
6
|
-
code >= 44032 && code <= 55215 || // 韩文音节
|
|
7
|
-
code >= 63744 && code <= 64255 || // CJK 兼容汉字
|
|
8
|
-
code >= 65072 && code <= 65103 || // CJK 兼容形式
|
|
9
|
-
code >= 65280 && code <= 65376 || // 全角 ASCII
|
|
10
|
-
code >= 65504 && code <= 65510 || // 全角符号
|
|
11
|
-
code >= 126976 && code <= 130047 || // 表情/符号
|
|
12
|
-
code >= 131072 && code <= 195103;
|
|
13
|
-
}
|
|
14
|
-
function displayWidth(str) {
|
|
15
|
-
const clean = str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
16
|
-
let width = 0;
|
|
17
|
-
for (const char of clean) {
|
|
18
|
-
width += isCJK(char) ? 2 : 1;
|
|
19
|
-
}
|
|
20
|
-
return width;
|
|
21
|
-
}
|
|
22
|
-
function padToWidth(str, targetWidth) {
|
|
23
|
-
const currentWidth = displayWidth(str);
|
|
24
|
-
const padding = targetWidth - currentWidth;
|
|
25
|
-
return padding > 0 ? str + " ".repeat(padding) : str;
|
|
26
|
-
}
|
|
27
|
-
function truncateToWidth(str, maxWidth) {
|
|
28
|
-
let width = 0;
|
|
29
|
-
let result = "";
|
|
30
|
-
for (const char of str) {
|
|
31
|
-
const charWidth = isCJK(char) ? 2 : 1;
|
|
32
|
-
if (width + charWidth > maxWidth - 1) {
|
|
33
|
-
result += "\u2026";
|
|
34
|
-
break;
|
|
35
|
-
}
|
|
36
|
-
result += char;
|
|
37
|
-
width += charWidth;
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export {
|
|
43
|
-
displayWidth,
|
|
44
|
-
padToWidth,
|
|
45
|
-
truncateToWidth
|
|
46
|
-
};
|
package/dist/chunk-CM423E2U.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HYPERCORE_DIR
|
|
3
|
-
} from "./chunk-SVF2VWOZ.js";
|
|
4
|
-
|
|
5
|
-
// src/core/instance-registry.ts
|
|
6
|
-
import { readFile, writeFile, unlink } from "fs/promises";
|
|
7
|
-
import { existsSync } from "fs";
|
|
8
|
-
import { join } from "path";
|
|
9
|
-
var REGISTRY_PATH = join(HYPERCORE_DIR, "instances.json");
|
|
10
|
-
var LOCK_PATH = join(HYPERCORE_DIR, "instances.lock");
|
|
11
|
-
function isPidAlive(pid) {
|
|
12
|
-
try {
|
|
13
|
-
process.kill(pid, 0);
|
|
14
|
-
return true;
|
|
15
|
-
} catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
async function withLock(fn) {
|
|
20
|
-
const maxRetries = 5;
|
|
21
|
-
const baseDelay = 50;
|
|
22
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
23
|
-
try {
|
|
24
|
-
await writeFile(LOCK_PATH, String(process.pid), { flag: "wx" });
|
|
25
|
-
try {
|
|
26
|
-
return await fn();
|
|
27
|
-
} finally {
|
|
28
|
-
await unlink(LOCK_PATH).catch(() => {
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
} catch (err) {
|
|
32
|
-
const code = err.code;
|
|
33
|
-
if (code === "EEXIST") {
|
|
34
|
-
try {
|
|
35
|
-
const lockPid = parseInt(await readFile(LOCK_PATH, "utf-8"), 10);
|
|
36
|
-
if (!isPidAlive(lockPid)) {
|
|
37
|
-
await unlink(LOCK_PATH).catch(() => {
|
|
38
|
-
});
|
|
39
|
-
} else {
|
|
40
|
-
await new Promise((r) => setTimeout(r, baseDelay * (i + 1)));
|
|
41
|
-
}
|
|
42
|
-
} catch {
|
|
43
|
-
await unlink(LOCK_PATH).catch(() => {
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
throw err;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
throw new Error("Failed to acquire instance registry lock after " + maxRetries + " retries");
|
|
52
|
-
}
|
|
53
|
-
async function readRegistry() {
|
|
54
|
-
try {
|
|
55
|
-
if (!existsSync(REGISTRY_PATH)) {
|
|
56
|
-
return { instances: [], lastUpdated: (/* @__PURE__ */ new Date()).toISOString() };
|
|
57
|
-
}
|
|
58
|
-
const data = JSON.parse(await readFile(REGISTRY_PATH, "utf-8"));
|
|
59
|
-
return data;
|
|
60
|
-
} catch {
|
|
61
|
-
return { instances: [], lastUpdated: (/* @__PURE__ */ new Date()).toISOString() };
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
async function writeRegistry(registry) {
|
|
65
|
-
registry.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
66
|
-
await writeFile(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
|
|
67
|
-
}
|
|
68
|
-
async function registerInstance(instance) {
|
|
69
|
-
await withLock(async () => {
|
|
70
|
-
const registry = await readRegistry();
|
|
71
|
-
registry.instances = registry.instances.filter(
|
|
72
|
-
(inst) => inst.pid !== instance.pid && isPidAlive(inst.pid)
|
|
73
|
-
);
|
|
74
|
-
registry.instances.push(instance);
|
|
75
|
-
await writeRegistry(registry);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
async function updateInstanceRuntime(pid, patch) {
|
|
79
|
-
if (Object.keys(patch).length === 0) return;
|
|
80
|
-
await withLock(async () => {
|
|
81
|
-
const registry = await readRegistry();
|
|
82
|
-
let changed = false;
|
|
83
|
-
const aliveInstances = registry.instances.filter((inst) => isPidAlive(inst.pid));
|
|
84
|
-
if (aliveInstances.length !== registry.instances.length) {
|
|
85
|
-
changed = true;
|
|
86
|
-
}
|
|
87
|
-
registry.instances = aliveInstances.map((inst) => {
|
|
88
|
-
if (inst.pid !== pid) return inst;
|
|
89
|
-
changed = true;
|
|
90
|
-
return { ...inst, ...patch };
|
|
91
|
-
});
|
|
92
|
-
if (changed) {
|
|
93
|
-
await writeRegistry(registry);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
async function unregisterInstance(pid) {
|
|
98
|
-
await withLock(async () => {
|
|
99
|
-
const registry = await readRegistry();
|
|
100
|
-
registry.instances = registry.instances.filter((inst) => inst.pid !== pid);
|
|
101
|
-
await writeRegistry(registry);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
async function listInstances() {
|
|
105
|
-
const registry = await readRegistry();
|
|
106
|
-
const alive = registry.instances.filter((inst) => isPidAlive(inst.pid));
|
|
107
|
-
if (alive.length !== registry.instances.length) {
|
|
108
|
-
withLock(async () => {
|
|
109
|
-
const fresh = await readRegistry();
|
|
110
|
-
fresh.instances = fresh.instances.filter((inst) => isPidAlive(inst.pid));
|
|
111
|
-
await writeRegistry(fresh);
|
|
112
|
-
}).catch(() => {
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
return alive;
|
|
116
|
-
}
|
|
117
|
-
async function getCanonicalDashboardPort(fallbackPort = 3210) {
|
|
118
|
-
try {
|
|
119
|
-
const instances = await listInstances();
|
|
120
|
-
if (instances.length === 0) return fallbackPort;
|
|
121
|
-
return Math.min(...instances.map((i) => i.port));
|
|
122
|
-
} catch {
|
|
123
|
-
return fallbackPort;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export {
|
|
128
|
-
registerInstance,
|
|
129
|
-
updateInstanceRuntime,
|
|
130
|
-
unregisterInstance,
|
|
131
|
-
listInstances,
|
|
132
|
-
getCanonicalDashboardPort
|
|
133
|
-
};
|