recallx-headless 1.0.8 → 1.2.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 +2 -0
- package/app/cli/src/cli.js +32 -1
- package/app/cli/src/format.js +24 -0
- package/app/mcp/index.js +2 -2
- package/app/mcp/server.js +523 -146
- package/app/server/app.js +413 -5
- package/app/server/config.js +4 -2
- package/app/server/index.js +12 -1
- package/app/server/observability.js +2 -0
- package/app/server/project-graph.js +13 -6
- package/app/server/repositories.js +178 -24
- package/app/server/sqlite-errors.js +10 -0
- package/app/server/workspace-import-helpers.js +161 -0
- package/app/server/workspace-import.js +572 -0
- package/app/server/workspace-ops.js +249 -0
- package/app/server/workspace-session.js +119 -7
- package/app/shared/contracts.js +41 -0
- package/app/shared/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -154,8 +154,10 @@ recallx workspace open --root /Users/name/Documents/RecallX-Test
|
|
|
154
154
|
- Default API base: `http://127.0.0.1:8787/api/v1`
|
|
155
155
|
- `recallx serve` starts the local RecallX API in-process from the installed package
|
|
156
156
|
- The CLI stays thin for day-to-day API operations and defers behavior to the HTTP API contract
|
|
157
|
+
- MCP tool results keep `structuredContent` as the authoritative payload; when possible the text mirror is a compact deterministic summary rather than a pretty JSON dump
|
|
157
158
|
- `--format json` is useful when scripting, while `--format markdown` is best for `context`
|
|
158
159
|
- `workspace open` switches the active workspace in the running local RecallX service without restarting the server
|
|
159
160
|
- `recallx-mcp` is the direct stdio MCP entrypoint from the npm package
|
|
161
|
+
- MCP tool results keep `structuredContent` authoritative and may render `content.text` as a compact deterministic summary instead of a pretty JSON mirror
|
|
160
162
|
- See the root [`README.md`](../../README.md) for source-run usage and install paths
|
|
161
163
|
- See [`docs/mcp.md`](../../docs/mcp.md) for editor MCP wiring details
|
package/app/cli/src/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
6
6
|
import { getApiBase, getAuthToken, requestJson } from "./http.js";
|
|
7
7
|
import { RECALLX_VERSION } from "../../shared/version.js";
|
|
8
8
|
import { applyCliUpdate, getCliUpdatePlan } from "./update.js";
|
|
9
|
-
import { renderActivitySearchResults, renderBundleMarkdown, renderGovernanceIssues, renderJson, renderNode, renderRelated, renderSearchResults, renderTelemetryErrors, renderTelemetrySummary, renderText, renderUpdateResult, renderWorkspaceSearchResults, renderWorkspaces, } from "./format.js";
|
|
9
|
+
import { renderActivitySearchResults, renderBundleMarkdown, renderGovernanceIssues, renderJson, renderNode, renderRelated, renderSearchResults, renderTelemetryErrors, renderTelemetrySummary, renderText, renderUpdateResult, renderWorkspaceBackups, renderWorkspaceSearchResults, renderWorkspaces, } from "./format.js";
|
|
10
10
|
const DEFAULT_SOURCE = {
|
|
11
11
|
actorType: "human",
|
|
12
12
|
actorLabel: "recallx-cli",
|
|
@@ -465,6 +465,27 @@ async function runWorkspace(apiBase, token, format, args, positionals) {
|
|
|
465
465
|
action,
|
|
466
466
|
rootPath: args.root || args.path || positionals[1],
|
|
467
467
|
});
|
|
468
|
+
case "backups": {
|
|
469
|
+
const data = await requestJson(apiBase, "/workspaces/backups", { token });
|
|
470
|
+
outputData(data, format, "workspace-backups");
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
case "backup":
|
|
474
|
+
return runPostCommand(apiBase, token, format, "/workspaces/backups", "workspace-backup", {
|
|
475
|
+
label: args.label || args.name || positionals[1],
|
|
476
|
+
});
|
|
477
|
+
case "export":
|
|
478
|
+
return runPostCommand(apiBase, token, format, "/workspaces/export", "workspace-export", {
|
|
479
|
+
format: args.format || args.kind || "json",
|
|
480
|
+
});
|
|
481
|
+
case "restore":
|
|
482
|
+
validateRequired(args.backup || args.id || positionals[1], "workspace restore requires --backup");
|
|
483
|
+
validateRequired(args.root || args.path || positionals[2], "workspace restore requires --root");
|
|
484
|
+
return runPostCommand(apiBase, token, format, "/workspaces/restore", "workspace-restore", {
|
|
485
|
+
backupId: args.backup || args.id || positionals[1],
|
|
486
|
+
targetRootPath: args.root || args.path || positionals[2],
|
|
487
|
+
workspaceName: args.name || args.title,
|
|
488
|
+
});
|
|
468
489
|
}
|
|
469
490
|
throw new Error(`Unknown workspace action: ${action}`);
|
|
470
491
|
}
|
|
@@ -547,6 +568,9 @@ function outputData(data, format, command) {
|
|
|
547
568
|
case "workspace-list":
|
|
548
569
|
writeStdout(renderWorkspaces(payload));
|
|
549
570
|
return;
|
|
571
|
+
case "workspace-backups":
|
|
572
|
+
writeStdout(renderWorkspaceBackups(payload));
|
|
573
|
+
return;
|
|
550
574
|
case "append":
|
|
551
575
|
case "create":
|
|
552
576
|
case "link":
|
|
@@ -557,6 +581,9 @@ function outputData(data, format, command) {
|
|
|
557
581
|
case "workspace-current":
|
|
558
582
|
case "workspace-create":
|
|
559
583
|
case "workspace-open":
|
|
584
|
+
case "workspace-backup":
|
|
585
|
+
case "workspace-export":
|
|
586
|
+
case "workspace-restore":
|
|
560
587
|
writeStdout(renderText(payload));
|
|
561
588
|
return;
|
|
562
589
|
case "observability-summary":
|
|
@@ -696,6 +723,10 @@ Usage:
|
|
|
696
723
|
recallx workspace list
|
|
697
724
|
recallx workspace create --root /path/to/workspace [--name "Personal"]
|
|
698
725
|
recallx workspace open --root /path/to/workspace
|
|
726
|
+
recallx workspace backups
|
|
727
|
+
recallx workspace backup [--label "before-upgrade"]
|
|
728
|
+
recallx workspace export [--format json|markdown]
|
|
729
|
+
recallx workspace restore --backup <id> --root /path/to/restore [--name "Recovered"]
|
|
699
730
|
recallx observability summary [--since 24h]
|
|
700
731
|
recallx observability errors [--since 24h] [--surface mcp] [--limit 50]
|
|
701
732
|
|
package/app/cli/src/format.js
CHANGED
|
@@ -144,6 +144,20 @@ export function renderWorkspaces(data) {
|
|
|
144
144
|
.join("\n\n")}\n`;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
export function renderWorkspaceBackups(data) {
|
|
148
|
+
const items = data?.items || [];
|
|
149
|
+
if (!items.length) {
|
|
150
|
+
return "No backups.\n";
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return `${items
|
|
154
|
+
.map(
|
|
155
|
+
(item, index) =>
|
|
156
|
+
`${index + 1}. ${item.label || item.id}\n id: ${item.id}\n created: ${item.createdAt}\n path: ${item.backupPath}`,
|
|
157
|
+
)
|
|
158
|
+
.join("\n\n")}\n`;
|
|
159
|
+
}
|
|
160
|
+
|
|
147
161
|
export function renderUpdateResult(data) {
|
|
148
162
|
const lines = [
|
|
149
163
|
`package: ${data?.packageName || ""}`,
|
|
@@ -206,8 +220,18 @@ export function renderTelemetrySummary(data) {
|
|
|
206
220
|
`since: ${data?.since || ""}`,
|
|
207
221
|
`logs: ${data?.logsPath || ""}`,
|
|
208
222
|
`events: ${data?.totalEvents ?? 0}`,
|
|
223
|
+
`slow threshold: ${data?.slowRequestThresholdMs ?? ""}ms`,
|
|
209
224
|
];
|
|
210
225
|
|
|
226
|
+
const hot = Array.isArray(data?.hotOperations) ? data.hotOperations : [];
|
|
227
|
+
if (hot.length > 0) {
|
|
228
|
+
lines.push("");
|
|
229
|
+
lines.push("Hot operations:");
|
|
230
|
+
for (const item of hot.slice(0, 5)) {
|
|
231
|
+
lines.push(`- [${item.surface}] ${item.operation} p95=${item.p95DurationMs ?? ""}ms errors=${item.errorCount}/${item.count}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
211
235
|
const slow = Array.isArray(data?.slowOperations) ? data.slowOperations : [];
|
|
212
236
|
if (slow.length > 0) {
|
|
213
237
|
lines.push("");
|
package/app/mcp/index.js
CHANGED
|
@@ -45,7 +45,7 @@ async function resolveObservabilityState() {
|
|
|
45
45
|
workspaceRoot: typeof workspace.rootPath === "string" ? workspace.rootPath : process.cwd(),
|
|
46
46
|
workspaceName: typeof workspace.workspaceName === "string" ? workspace.workspaceName : "RecallX MCP",
|
|
47
47
|
retentionDays: typeof values["observability.retentionDays"] === "number" ? values["observability.retentionDays"] : 14,
|
|
48
|
-
slowRequestMs: typeof values["observability.slowRequestMs"] === "number" ? values["observability.slowRequestMs"] :
|
|
48
|
+
slowRequestMs: typeof values["observability.slowRequestMs"] === "number" ? values["observability.slowRequestMs"] : 50,
|
|
49
49
|
capturePayloadShape: values["observability.capturePayloadShape"] !== false
|
|
50
50
|
};
|
|
51
51
|
}
|
|
@@ -55,7 +55,7 @@ async function resolveObservabilityState() {
|
|
|
55
55
|
workspaceRoot: process.cwd(),
|
|
56
56
|
workspaceName: "RecallX MCP",
|
|
57
57
|
retentionDays: 14,
|
|
58
|
-
slowRequestMs:
|
|
58
|
+
slowRequestMs: 50,
|
|
59
59
|
capturePayloadShape: true
|
|
60
60
|
};
|
|
61
61
|
}
|