@orquentra/codebuddy 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/adapters-S4HHTWJW.js +24 -0
- package/dist/{chunk-EEUFU7KV.js → chunk-6DONJW3W.js} +163 -22
- package/dist/chunk-6DONJW3W.js.map +1 -0
- package/dist/{chunk-JUAFCLRB.js → chunk-6KGYAFG7.js} +2 -2
- package/dist/{chunk-JUAFCLRB.js.map → chunk-6KGYAFG7.js.map} +1 -1
- package/dist/{chunk-BQM7FJ7D.js → chunk-6NZEZJYD.js} +5 -3
- package/dist/{chunk-BQM7FJ7D.js.map → chunk-6NZEZJYD.js.map} +1 -1
- package/dist/{chunk-AQHPEJR6.js → chunk-EJQVGFH2.js} +2 -2
- package/dist/{chunk-MSUAVR3R.js → chunk-GXOML4UZ.js} +2 -2
- package/dist/chunk-ITQO632W.js +673 -0
- package/dist/chunk-ITQO632W.js.map +1 -0
- package/dist/chunk-J4T6HHI4.js +1444 -0
- package/dist/chunk-J4T6HHI4.js.map +1 -0
- package/dist/{chunk-AK2UAE32.js → chunk-NY2YXP3R.js} +2 -2
- package/dist/{chunk-5EDGAZQN.js → chunk-TLWGZVPC.js} +64 -725
- package/dist/chunk-TLWGZVPC.js.map +1 -0
- package/dist/{chunk-LCSBL5TT.js → chunk-UK6XTS2Y.js} +5 -3
- package/dist/{chunk-LCSBL5TT.js.map → chunk-UK6XTS2Y.js.map} +1 -1
- package/dist/chunk-W7GAXL6C.js +104 -0
- package/dist/chunk-W7GAXL6C.js.map +1 -0
- package/dist/{chunk-TUR6YKEE.js → chunk-XL2HLACE.js} +1 -1
- package/dist/chunk-XL2HLACE.js.map +1 -0
- package/dist/{chunk-YJIA2MFL.js → chunk-ZNLSCV3J.js} +15 -13
- package/dist/{chunk-YJIA2MFL.js.map → chunk-ZNLSCV3J.js.map} +1 -1
- package/dist/cli/index.js +4 -4
- package/dist/index.js +9 -8
- package/dist/install-BXM56QCD.js +19 -0
- package/dist/{lean-command-CWJAVQ5G.js → lean-command-7DFW32MA.js} +4 -3
- package/dist/{main-AHNGHC4L.js → main-QUASSFP7.js} +902 -1686
- package/dist/main-QUASSFP7.js.map +1 -0
- package/dist/{operations-7BTAAUHF.js → operations-WJR7AZZF.js} +3 -3
- package/dist/{pretool-command-3SXQSMAO.js → pretool-command-JTKX6G3M.js} +3 -3
- package/dist/{runtime-E7JQZ2BZ.js → runtime-OQQ22VJF.js} +7 -6
- package/dist/{summaries-XV3JGGCC.js → summaries-ML53R7EL.js} +4 -3
- package/dist/summaries-ML53R7EL.js.map +1 -0
- package/dist/{zvec-KP4KNB7Y.js → zvec-XDZNZ2OL.js} +4 -3
- package/dist/zvec-XDZNZ2OL.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-5EDGAZQN.js.map +0 -1
- package/dist/chunk-EEUFU7KV.js.map +0 -1
- package/dist/chunk-TUR6YKEE.js.map +0 -1
- package/dist/main-AHNGHC4L.js.map +0 -1
- /package/dist/{lean-command-CWJAVQ5G.js.map → adapters-S4HHTWJW.js.map} +0 -0
- /package/dist/{chunk-AQHPEJR6.js.map → chunk-EJQVGFH2.js.map} +0 -0
- /package/dist/{chunk-MSUAVR3R.js.map → chunk-GXOML4UZ.js.map} +0 -0
- /package/dist/{chunk-AK2UAE32.js.map → chunk-NY2YXP3R.js.map} +0 -0
- /package/dist/{operations-7BTAAUHF.js.map → install-BXM56QCD.js.map} +0 -0
- /package/dist/{pretool-command-3SXQSMAO.js.map → lean-command-7DFW32MA.js.map} +0 -0
- /package/dist/{runtime-E7JQZ2BZ.js.map → operations-WJR7AZZF.js.map} +0 -0
- /package/dist/{summaries-XV3JGGCC.js.map → pretool-command-JTKX6G3M.js.map} +0 -0
- /package/dist/{zvec-KP4KNB7Y.js.map → runtime-OQQ22VJF.js.map} +0 -0
package/README.md
CHANGED
|
@@ -52,6 +52,15 @@ This opens a live local page showing:
|
|
|
52
52
|
|
|
53
53
|
It updates as you work, and the traces never leave your machine.
|
|
54
54
|
|
|
55
|
+
## Telemetry
|
|
56
|
+
|
|
57
|
+
CodeBuddy sends anonymous usage counts (tool names, timings, success, version,
|
|
58
|
+
OS, agent client) so we can see which features are used. Prompts, code, file
|
|
59
|
+
paths and repository names are never sent, and nothing is sent until a notice
|
|
60
|
+
has been shown once in your terminal. Opt out with `codebuddy telemetry disable`,
|
|
61
|
+
`CODEBUDDY_TELEMETRY=0` or `DO_NOT_TRACK=1`; CI never sends. Details:
|
|
62
|
+
[docs/telemetry.md](https://github.com/Orquentra-Inc/CodeBuddy/blob/main/docs/telemetry.md).
|
|
63
|
+
|
|
55
64
|
## Try it without a database
|
|
56
65
|
|
|
57
66
|
```bash
|
|
@@ -66,6 +75,7 @@ needs more detail. Inspect missing or truncated evidence before editing.
|
|
|
66
75
|
## Documentation
|
|
67
76
|
|
|
68
77
|
- [Full guide and examples](https://github.com/Orquentra-Inc/CodeBuddy/blob/348bb7c/README.md)
|
|
78
|
+
- [Telemetry and the admin panel](https://github.com/Orquentra-Inc/CodeBuddy/blob/main/docs/telemetry.md)
|
|
69
79
|
- [Token budgets](https://github.com/Orquentra-Inc/CodeBuddy/blob/main/docs/token-budgets.md)
|
|
70
80
|
- [Optional LLM setup](https://github.com/Orquentra-Inc/CodeBuddy/blob/main/docs/llm-byok.md)
|
|
71
81
|
- [Source and issues](https://github.com/Orquentra-Inc/CodeBuddy)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AUTOMATION_MODES,
|
|
3
|
+
CLIENT_ADAPTERS,
|
|
4
|
+
CLIENT_IDS,
|
|
5
|
+
LIFECYCLE_EVENTS,
|
|
6
|
+
MODE_LABELS,
|
|
7
|
+
parseClient,
|
|
8
|
+
parseMode,
|
|
9
|
+
sharedRulesReaders,
|
|
10
|
+
supportedModes
|
|
11
|
+
} from "./chunk-W7GAXL6C.js";
|
|
12
|
+
import "./chunk-PZ5AY32C.js";
|
|
13
|
+
export {
|
|
14
|
+
AUTOMATION_MODES,
|
|
15
|
+
CLIENT_ADAPTERS,
|
|
16
|
+
CLIENT_IDS,
|
|
17
|
+
LIFECYCLE_EVENTS,
|
|
18
|
+
MODE_LABELS,
|
|
19
|
+
parseClient,
|
|
20
|
+
parseMode,
|
|
21
|
+
sharedRulesReaders,
|
|
22
|
+
supportedModes
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=adapters-S4HHTWJW.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
refreshZvecIndex
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GXOML4UZ.js";
|
|
4
4
|
import {
|
|
5
5
|
PlanFileStore,
|
|
6
6
|
PlanLifecycle,
|
|
@@ -13,33 +13,36 @@ import {
|
|
|
13
13
|
llmMemoryOptions,
|
|
14
14
|
readPolicyFile,
|
|
15
15
|
resolveRiskPaths
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import {
|
|
18
|
-
recordTrace
|
|
19
|
-
} from "./chunk-TUR6YKEE.js";
|
|
16
|
+
} from "./chunk-ZNLSCV3J.js";
|
|
20
17
|
import {
|
|
21
18
|
SessionCapsuleLedger,
|
|
22
19
|
coveringTestCandidates,
|
|
23
20
|
estimateTokens
|
|
24
21
|
} from "./chunk-GKNYMNFM.js";
|
|
22
|
+
import {
|
|
23
|
+
readTraces,
|
|
24
|
+
recordTrace
|
|
25
|
+
} from "./chunk-XL2HLACE.js";
|
|
25
26
|
import {
|
|
26
27
|
codeBuddyConfigSchema,
|
|
27
28
|
createRuntime,
|
|
28
29
|
listFactsPage
|
|
29
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-NY2YXP3R.js";
|
|
30
31
|
import {
|
|
31
32
|
MemoryFileStore,
|
|
32
33
|
VERSION
|
|
33
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-6KGYAFG7.js";
|
|
34
35
|
import {
|
|
35
|
-
buildArchitectureMap,
|
|
36
36
|
generateGraphifyGraph,
|
|
37
|
+
loadProjectArchitectureMap
|
|
38
|
+
} from "./chunk-TLWGZVPC.js";
|
|
39
|
+
import {
|
|
40
|
+
buildArchitectureMap,
|
|
37
41
|
indexRepository,
|
|
38
42
|
loadFreshIndex,
|
|
39
|
-
loadProjectArchitectureMap,
|
|
40
43
|
neighbours,
|
|
41
44
|
queryMap
|
|
42
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-ITQO632W.js";
|
|
43
46
|
import {
|
|
44
47
|
redactPersisted
|
|
45
48
|
} from "./chunk-AL6VBTNA.js";
|
|
@@ -167,11 +170,138 @@ function checksum(content) {
|
|
|
167
170
|
return createHash("sha256").update(content).digest("hex");
|
|
168
171
|
}
|
|
169
172
|
|
|
173
|
+
// src/telemetry/telemetry.ts
|
|
174
|
+
import { createHash as createHash2, randomUUID } from "crypto";
|
|
175
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
176
|
+
import { homedir } from "os";
|
|
177
|
+
import { dirname, join } from "path";
|
|
178
|
+
var TELEMETRY_URL = "https://tanmay-hp-linux-server.tail41864f.ts.net/v1/events";
|
|
179
|
+
var FLUSH_INTERVAL_MS = 10 * 6e4;
|
|
180
|
+
var MAX_EVENTS = 500;
|
|
181
|
+
var SEND_TIMEOUT_MS = 3e3;
|
|
182
|
+
var NAME = /^[A-Za-z][A-Za-z0-9_:.-]{0,63}$/;
|
|
183
|
+
function telemetryStatePath(home = homedir()) {
|
|
184
|
+
return join(home, ".codebuddy", "telemetry.json");
|
|
185
|
+
}
|
|
186
|
+
async function readTelemetryState(home = homedir()) {
|
|
187
|
+
try {
|
|
188
|
+
const state = JSON.parse(await readFile(telemetryStatePath(home), "utf8"));
|
|
189
|
+
if (typeof state.installId === "string" && state.installId) return state;
|
|
190
|
+
} catch {
|
|
191
|
+
}
|
|
192
|
+
return writeTelemetryState({ installId: randomUUID() }, home);
|
|
193
|
+
}
|
|
194
|
+
async function writeTelemetryState(state, home = homedir()) {
|
|
195
|
+
const path = telemetryStatePath(home);
|
|
196
|
+
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
197
|
+
await writeFile(path, `${JSON.stringify(state, null, 2)}
|
|
198
|
+
`, { mode: 384 });
|
|
199
|
+
return state;
|
|
200
|
+
}
|
|
201
|
+
function telemetryBlocked(state, env = process.env) {
|
|
202
|
+
if (env.CODEBUDDY_TELEMETRY === "0") return "CODEBUDDY_TELEMETRY=0";
|
|
203
|
+
if (env.DO_NOT_TRACK === "1" || env.DO_NOT_TRACK === "true") return "DO_NOT_TRACK";
|
|
204
|
+
if (env.CI) return "CI";
|
|
205
|
+
if (state.disabled) return "disabled with `codebuddy telemetry disable`";
|
|
206
|
+
if (!telemetryUrl(env)) return "no collector configured";
|
|
207
|
+
if (!state.noticeAt) return "first-run notice not shown yet";
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
function telemetryUrl(env = process.env) {
|
|
211
|
+
return env.CODEBUDDY_TELEMETRY_URL ?? TELEMETRY_URL;
|
|
212
|
+
}
|
|
213
|
+
var TELEMETRY_NOTICE = `CodeBuddy collects anonymous usage data (which tools run, how long they take,
|
|
214
|
+
success/failure, version, OS, agent client) to improve the product.
|
|
215
|
+
Prompts, code, file paths and repository names are never sent.
|
|
216
|
+
Opt out any time: \`codebuddy telemetry disable\` or CODEBUDDY_TELEMETRY=0.
|
|
217
|
+
Details: https://github.com/Orquentra-Inc/CodeBuddy/blob/main/docs/telemetry.md`;
|
|
218
|
+
async function showTelemetryNoticeOnce(write = (text) => process.stderr.write(text), options = {}) {
|
|
219
|
+
const env = options.env ?? process.env;
|
|
220
|
+
if (!(options.tty ?? process.stderr.isTTY)) return;
|
|
221
|
+
try {
|
|
222
|
+
const state = await readTelemetryState(options.home);
|
|
223
|
+
if (state.noticeAt || state.disabled || env.CODEBUDDY_TELEMETRY === "0" || env.CI) return;
|
|
224
|
+
if (!telemetryUrl(env)) return;
|
|
225
|
+
write(`
|
|
226
|
+
${TELEMETRY_NOTICE}
|
|
227
|
+
|
|
228
|
+
`);
|
|
229
|
+
await writeTelemetryState({ ...state, noticeAt: (/* @__PURE__ */ new Date()).toISOString() }, options.home);
|
|
230
|
+
} catch {
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function anonymize(installId, value) {
|
|
234
|
+
return createHash2("sha256").update(`${installId}\0${value}`).digest("hex").slice(0, 16);
|
|
235
|
+
}
|
|
236
|
+
function toTelemetryEvents(installId, traces) {
|
|
237
|
+
return traces.map((trace) => ({
|
|
238
|
+
ts: trace.ts,
|
|
239
|
+
kind: NAME.test(trace.kind) ? trace.kind : "other",
|
|
240
|
+
name: NAME.test(trace.name) ? trace.name : "other",
|
|
241
|
+
ms: Math.max(0, Math.round(trace.ms) || 0),
|
|
242
|
+
ok: trace.ok === true,
|
|
243
|
+
...typeof trace.tokensIn === "number" ? { tokensIn: trace.tokensIn } : {},
|
|
244
|
+
...typeof trace.tokensOut === "number" ? { tokensOut: trace.tokensOut } : {},
|
|
245
|
+
...trace.session ? { session: anonymize(installId, trace.session) } : {}
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
248
|
+
async function flushTelemetry(repositoryRoot, options = {}) {
|
|
249
|
+
const env = options.env ?? process.env;
|
|
250
|
+
const now = options.now ?? Date.now();
|
|
251
|
+
try {
|
|
252
|
+
const state = await readTelemetryState(options.home);
|
|
253
|
+
if (telemetryBlocked(state, env)) return 0;
|
|
254
|
+
const cursorPath = join(repositoryRoot, ".codebuddy", "cache", "telemetry.json");
|
|
255
|
+
const cursor = await readFile(cursorPath, "utf8").then((raw) => JSON.parse(raw)).catch(() => ({}));
|
|
256
|
+
if (cursor.flushedAt && now - cursor.flushedAt < FLUSH_INTERVAL_MS) return 0;
|
|
257
|
+
const save = (next) => mkdir(dirname(cursorPath), { recursive: true }).then(
|
|
258
|
+
() => writeFile(cursorPath, JSON.stringify(next))
|
|
259
|
+
);
|
|
260
|
+
await save({ ...cursor, flushedAt: now });
|
|
261
|
+
const pending = (await readTraces(repositoryRoot, 1e4)).filter((trace) => !cursor.sentTs || trace.ts > cursor.sentTs).slice(-MAX_EVENTS);
|
|
262
|
+
const last = pending.at(-1);
|
|
263
|
+
if (!last) return 0;
|
|
264
|
+
const batch = {
|
|
265
|
+
installId: state.installId,
|
|
266
|
+
project: anonymize(state.installId, repositoryRoot),
|
|
267
|
+
version: VERSION,
|
|
268
|
+
platform: process.platform,
|
|
269
|
+
arch: process.arch,
|
|
270
|
+
node: process.versions.node.split(".")[0] ?? "",
|
|
271
|
+
clients: await (options.clients ?? (() => installedClients(repositoryRoot)))().catch(
|
|
272
|
+
() => []
|
|
273
|
+
),
|
|
274
|
+
events: toTelemetryEvents(state.installId, pending)
|
|
275
|
+
};
|
|
276
|
+
const response = await (options.fetchImpl ?? fetch)(telemetryUrl(env), {
|
|
277
|
+
method: "POST",
|
|
278
|
+
headers: { "content-type": "application/json" },
|
|
279
|
+
body: JSON.stringify(batch),
|
|
280
|
+
signal: AbortSignal.timeout(SEND_TIMEOUT_MS)
|
|
281
|
+
});
|
|
282
|
+
if (!response.ok) return 0;
|
|
283
|
+
await save({ sentTs: last.ts, flushedAt: now });
|
|
284
|
+
return batch.events.length;
|
|
285
|
+
} catch {
|
|
286
|
+
return 0;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
async function installedClients(repositoryRoot) {
|
|
290
|
+
const { CLIENT_IDS } = await import("./adapters-S4HHTWJW.js");
|
|
291
|
+
const { detectClient } = await import("./install-BXM56QCD.js");
|
|
292
|
+
const found = [];
|
|
293
|
+
for (const id of CLIENT_IDS) {
|
|
294
|
+
const status = await detectClient(id, repositoryRoot).catch(() => null);
|
|
295
|
+
if (status && (status.hooks || status.mcp)) found.push(id);
|
|
296
|
+
}
|
|
297
|
+
return found;
|
|
298
|
+
}
|
|
299
|
+
|
|
170
300
|
// src/mcp/tools/index.ts
|
|
171
301
|
import { z } from "zod";
|
|
172
302
|
|
|
173
303
|
// src/context/delivery.ts
|
|
174
|
-
import { createHash as
|
|
304
|
+
import { createHash as createHash3 } from "crypto";
|
|
175
305
|
var DELIVERY_VERSION = 1;
|
|
176
306
|
var OMITTABLE_SECTIONS = [
|
|
177
307
|
"plan",
|
|
@@ -190,7 +320,7 @@ async function applySessionDelivery(repositoryRoot, payload, options) {
|
|
|
190
320
|
if (!options.sessionId) return output;
|
|
191
321
|
const sections = OMITTABLE_SECTIONS.filter((key) => output[key] !== void 0).map((key) => ({
|
|
192
322
|
key: `mcp:${key}`,
|
|
193
|
-
hash:
|
|
323
|
+
hash: createHash3("sha256").update(JSON.stringify(output[key])).digest("hex")
|
|
194
324
|
}));
|
|
195
325
|
try {
|
|
196
326
|
await new SessionCapsuleLedger(repositoryRoot).exchange(options.sessionId, sections, {
|
|
@@ -217,7 +347,7 @@ async function applySessionDelivery(repositoryRoot, payload, options) {
|
|
|
217
347
|
output = enforceContextBudget(output);
|
|
218
348
|
return OMITTABLE_SECTIONS.filter((key) => output[key] !== void 0).map((key) => ({
|
|
219
349
|
key: `mcp:${key}`,
|
|
220
|
-
hash:
|
|
350
|
+
hash: createHash3("sha256").update(JSON.stringify(output[key])).digest("hex")
|
|
221
351
|
}));
|
|
222
352
|
}
|
|
223
353
|
});
|
|
@@ -230,7 +360,7 @@ async function applySessionDelivery(repositoryRoot, payload, options) {
|
|
|
230
360
|
// src/suggest/engine.ts
|
|
231
361
|
import { constants } from "fs";
|
|
232
362
|
import { access } from "fs/promises";
|
|
233
|
-
import { extname, join, resolve } from "path";
|
|
363
|
+
import { extname, join as join2, resolve } from "path";
|
|
234
364
|
|
|
235
365
|
// src/suggest/types.ts
|
|
236
366
|
var SEVERITY_RANK = {
|
|
@@ -267,7 +397,7 @@ async function generateSuggestions(input) {
|
|
|
267
397
|
resolveRelevantPlan(planStore, namespace, input.planId),
|
|
268
398
|
memoryStore.findIncidentFactsForPaths({ namespace, paths: targetPaths }),
|
|
269
399
|
buildArchitectureMap(repositoryRoot),
|
|
270
|
-
readPolicyFile(
|
|
400
|
+
readPolicyFile(join2(repositoryRoot, ".codebuddy", "policies.yaml"))
|
|
271
401
|
]);
|
|
272
402
|
const suggestions = [];
|
|
273
403
|
for (const item of risks.items) {
|
|
@@ -347,7 +477,7 @@ async function generateSuggestions(input) {
|
|
|
347
477
|
for (const rule of policyFile.rules) {
|
|
348
478
|
const prefix = literalPrefix(rule.pattern);
|
|
349
479
|
if (!prefix) continue;
|
|
350
|
-
if (await pathExists(
|
|
480
|
+
if (await pathExists(join2(repositoryRoot, prefix))) continue;
|
|
351
481
|
suggestions.push({
|
|
352
482
|
id: `stale_policy:${rule.id}`,
|
|
353
483
|
category: "stale_policy",
|
|
@@ -391,7 +521,7 @@ function isTestableCode(path) {
|
|
|
391
521
|
}
|
|
392
522
|
async function hasSiblingTest(repositoryRoot, path) {
|
|
393
523
|
for (const candidate of coveringTestCandidates(path)) {
|
|
394
|
-
if (await pathExists(
|
|
524
|
+
if (await pathExists(join2(repositoryRoot, candidate))) return true;
|
|
395
525
|
}
|
|
396
526
|
return false;
|
|
397
527
|
}
|
|
@@ -1146,7 +1276,7 @@ import pino from "pino";
|
|
|
1146
1276
|
|
|
1147
1277
|
// src/automation/project-sync.ts
|
|
1148
1278
|
import { watch as fsWatch2 } from "fs";
|
|
1149
|
-
import { join as
|
|
1279
|
+
import { join as join3, relative, resolve as resolve3, sep } from "path";
|
|
1150
1280
|
|
|
1151
1281
|
// src/indexer/watch.ts
|
|
1152
1282
|
import { watch as fsWatch } from "fs";
|
|
@@ -1327,7 +1457,7 @@ function startProjectSync(options) {
|
|
|
1327
1457
|
300
|
|
1328
1458
|
);
|
|
1329
1459
|
memoryWatcher = fsWatch2(
|
|
1330
|
-
|
|
1460
|
+
join3(repositoryRoot, ".codebuddy", "memory"),
|
|
1331
1461
|
{ recursive: true },
|
|
1332
1462
|
(_event, filename) => {
|
|
1333
1463
|
const name = filename?.replace(/\\/g, "/") ?? "";
|
|
@@ -1361,7 +1491,7 @@ function startProjectSync(options) {
|
|
|
1361
1491
|
|
|
1362
1492
|
// src/core/project-root.ts
|
|
1363
1493
|
import { realpath, stat } from "fs/promises";
|
|
1364
|
-
import { homedir } from "os";
|
|
1494
|
+
import { homedir as homedir2 } from "os";
|
|
1365
1495
|
import { isAbsolute, parse, resolve as resolve4 } from "path";
|
|
1366
1496
|
async function resolveInitializedProjectRoot(configuredRoot, cwd = process.cwd()) {
|
|
1367
1497
|
if (configuredRoot !== void 0 && !isAbsolute(configuredRoot)) {
|
|
@@ -1369,7 +1499,7 @@ async function resolveInitializedProjectRoot(configuredRoot, cwd = process.cwd()
|
|
|
1369
1499
|
}
|
|
1370
1500
|
const selected = resolve4(configuredRoot ?? cwd);
|
|
1371
1501
|
const root = await realpath(selected);
|
|
1372
|
-
if (root === parse(root).root || root === await realpath(
|
|
1502
|
+
if (root === parse(root).root || root === await realpath(homedir2())) {
|
|
1373
1503
|
throw new Error(
|
|
1374
1504
|
"Select an initialized project folder, not the filesystem root or home folder."
|
|
1375
1505
|
);
|
|
@@ -1519,8 +1649,11 @@ async function startMcpServer(options = {}) {
|
|
|
1519
1649
|
});
|
|
1520
1650
|
const server = new McpServer({ name: "codebuddy", version: VERSION });
|
|
1521
1651
|
registerCodeBuddyTools(server, { config, database }, toolProfile);
|
|
1652
|
+
const telemetry = setInterval(() => void flushTelemetry(projectRoot), 6e4);
|
|
1653
|
+
telemetry.unref();
|
|
1522
1654
|
const shutdown = async () => {
|
|
1523
1655
|
logger.info("codebuddy MCP server shutting down");
|
|
1656
|
+
clearInterval(telemetry);
|
|
1524
1657
|
await server.close();
|
|
1525
1658
|
await sync.close();
|
|
1526
1659
|
await database.close();
|
|
@@ -1626,9 +1759,17 @@ function isConnectionRefused(error) {
|
|
|
1626
1759
|
export {
|
|
1627
1760
|
migrateMemoryToFiles,
|
|
1628
1761
|
watchRepository,
|
|
1762
|
+
telemetryStatePath,
|
|
1763
|
+
readTelemetryState,
|
|
1764
|
+
writeTelemetryState,
|
|
1765
|
+
telemetryBlocked,
|
|
1766
|
+
telemetryUrl,
|
|
1767
|
+
TELEMETRY_NOTICE,
|
|
1768
|
+
showTelemetryNoticeOnce,
|
|
1769
|
+
flushTelemetry,
|
|
1629
1770
|
generateSuggestions,
|
|
1630
1771
|
mcpToolInputSchemas,
|
|
1631
1772
|
registerCodeBuddyTools,
|
|
1632
1773
|
startMcpServer
|
|
1633
1774
|
};
|
|
1634
|
-
//# sourceMappingURL=chunk-
|
|
1775
|
+
//# sourceMappingURL=chunk-6DONJW3W.js.map
|