memorix 1.8.0 → 1.8.1
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/CHANGELOG.md +9 -0
- package/dist/cli/index.js +83 -80
- package/dist/dashboard/static/app.js +37 -23
- package/dist/dashboard/static/index.html +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +54 -78
- package/dist/memcode-runtime/CHANGELOG.md +9 -0
- package/dist/sdk.js +53 -77
- package/docs/API_REFERENCE.md +2 -0
- package/docs/ARCHITECTURE.md +3 -1
- package/docs/DASHBOARD.md +6 -0
- package/docs/DEVELOPMENT.md +2 -2
- package/docs/README.md +5 -2
- package/package.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/cli/commands/dashboard.ts +1 -1
- package/src/cli/commands/serve-http.ts +28 -1
- package/src/dashboard/server.ts +85 -86
- package/src/dashboard/static/index.html +1 -1
- package/src/server.ts +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.8.1] - 2026-08-24
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- **Truthful coordination status** -- the persistent SQLite `TeamStore` is the
|
|
11
|
+
sole coordination truth for agents, tasks, messages, locks, handoffs, and poll
|
|
12
|
+
state. The Dashboard exposes read-only `Coordination Status` and `Task Status`
|
|
13
|
+
views, and `/api/team` reports explicit `error` or `degraded` status instead of
|
|
14
|
+
presenting a failed coordination read as a healthy empty result.
|
|
15
|
+
|
|
7
16
|
## [1.8.0] - 2026-08-23
|
|
8
17
|
|
|
9
18
|
### Added
|
package/dist/cli/index.js
CHANGED
|
@@ -3232,7 +3232,7 @@ ${import_picocolors.default.gray(m3)} ${s4}
|
|
|
3232
3232
|
|
|
3233
3233
|
// src/cli/version.ts
|
|
3234
3234
|
function getCliVersion() {
|
|
3235
|
-
return true ? "1.8.
|
|
3235
|
+
return true ? "1.8.1" : pkg.version;
|
|
3236
3236
|
}
|
|
3237
3237
|
var init_version = __esm({
|
|
3238
3238
|
"src/cli/version.ts"() {
|
|
@@ -220770,6 +220770,37 @@ function normalizeDashboardTask(task) {
|
|
|
220770
220770
|
preferredRole: task.preferred_role ?? task.preferredRole ?? null
|
|
220771
220771
|
};
|
|
220772
220772
|
}
|
|
220773
|
+
function emptyTeamSnapshot(mode, scope, status) {
|
|
220774
|
+
return {
|
|
220775
|
+
status,
|
|
220776
|
+
mode,
|
|
220777
|
+
readOnly: true,
|
|
220778
|
+
scope,
|
|
220779
|
+
agents: [],
|
|
220780
|
+
activeCount: 0,
|
|
220781
|
+
recentCount: 0,
|
|
220782
|
+
historicalCount: 0,
|
|
220783
|
+
totalAgents: 0,
|
|
220784
|
+
recentWindowDays: 7,
|
|
220785
|
+
locks: [],
|
|
220786
|
+
tasks: [],
|
|
220787
|
+
availableTasks: 0,
|
|
220788
|
+
sessions: 0,
|
|
220789
|
+
roles: [],
|
|
220790
|
+
roleOccupancy: [],
|
|
220791
|
+
handoffs: [],
|
|
220792
|
+
openTasks: 0,
|
|
220793
|
+
openHandoffs: 0,
|
|
220794
|
+
totalUnread: 0,
|
|
220795
|
+
activeSessions: 0,
|
|
220796
|
+
error: status === "error" ? "Coordination state unavailable" : "Coordination state is incomplete",
|
|
220797
|
+
errorCode: status === "error" ? "COORDINATION_STATE_UNAVAILABLE" : "COORDINATION_STATE_DEGRADED"
|
|
220798
|
+
};
|
|
220799
|
+
}
|
|
220800
|
+
function logTeamSnapshotFailure(scope, status) {
|
|
220801
|
+
const safeScope = scope === "global" ? "global" : "project";
|
|
220802
|
+
console.error("[dashboard] coordination snapshot unavailable", { status, scope: safeScope });
|
|
220803
|
+
}
|
|
220773
220804
|
async function buildTeamSnapshot(dataDir, projectId, scope, mode) {
|
|
220774
220805
|
try {
|
|
220775
220806
|
const { initTeamStore: initTeamStore2 } = await Promise.resolve().then(() => (init_team_store(), team_store_exports));
|
|
@@ -220796,8 +220827,9 @@ async function buildTeamSnapshot(dataDir, projectId, scope, mode) {
|
|
|
220796
220827
|
const roleOccupancy = effectiveProjectId ? teamStore.getRoleOccupancy(effectiveProjectId) : [];
|
|
220797
220828
|
const handoffs = effectiveProjectId ? teamStore.listHandoffs(effectiveProjectId) : [];
|
|
220798
220829
|
return {
|
|
220830
|
+
status: "ok",
|
|
220799
220831
|
mode,
|
|
220800
|
-
readOnly:
|
|
220832
|
+
readOnly: true,
|
|
220801
220833
|
scope,
|
|
220802
220834
|
agents: withTier,
|
|
220803
220835
|
activeCount,
|
|
@@ -220818,28 +220850,8 @@ async function buildTeamSnapshot(dataDir, projectId, scope, mode) {
|
|
|
220818
220850
|
activeSessions: activeCount
|
|
220819
220851
|
};
|
|
220820
220852
|
} catch {
|
|
220821
|
-
|
|
220822
|
-
|
|
220823
|
-
readOnly: mode === "standalone",
|
|
220824
|
-
scope,
|
|
220825
|
-
agents: [],
|
|
220826
|
-
activeCount: 0,
|
|
220827
|
-
recentCount: 0,
|
|
220828
|
-
historicalCount: 0,
|
|
220829
|
-
totalAgents: 0,
|
|
220830
|
-
recentWindowDays: 7,
|
|
220831
|
-
locks: [],
|
|
220832
|
-
tasks: [],
|
|
220833
|
-
availableTasks: 0,
|
|
220834
|
-
sessions: 0,
|
|
220835
|
-
roles: [],
|
|
220836
|
-
roleOccupancy: [],
|
|
220837
|
-
handoffs: [],
|
|
220838
|
-
openTasks: 0,
|
|
220839
|
-
openHandoffs: 0,
|
|
220840
|
-
totalUnread: 0,
|
|
220841
|
-
activeSessions: 0
|
|
220842
|
-
};
|
|
220853
|
+
logTeamSnapshotFailure(scope, "error");
|
|
220854
|
+
return emptyTeamSnapshot(mode, scope, "error");
|
|
220843
220855
|
}
|
|
220844
220856
|
}
|
|
220845
220857
|
function readBody(req) {
|
|
@@ -220858,13 +220870,12 @@ function readBody(req) {
|
|
|
220858
220870
|
req.on("error", reject);
|
|
220859
220871
|
});
|
|
220860
220872
|
}
|
|
220861
|
-
async function startDashboard(dataDir, port, staticDir, projectId, projectName, autoOpen = true,
|
|
220873
|
+
async function startDashboard(dataDir, port, staticDir, projectId, projectName, autoOpen = true, projectRoot = null, projectResolved = true) {
|
|
220862
220874
|
await initObservationStore(dataDir);
|
|
220863
220875
|
await initSessionStore(dataDir);
|
|
220864
220876
|
const resolvedStaticDir = staticDir;
|
|
220865
220877
|
const baseDir = getBaseDataDir();
|
|
220866
|
-
const
|
|
220867
|
-
const state = { projectId, projectName, dataDir, projectRoot, projectResolved, mode: isControlPlane ? "control-plane" : "standalone", port };
|
|
220878
|
+
const state = { projectId, projectName, dataDir, projectRoot, projectResolved, mode: "standalone", port };
|
|
220868
220879
|
const server = createServer(async (req, res) => {
|
|
220869
220880
|
const url2 = req.url || "/";
|
|
220870
220881
|
if (url2.startsWith("/api/set-current-project") && req.method === "POST") {
|
|
@@ -220886,54 +220897,20 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
|
|
|
220886
220897
|
}
|
|
220887
220898
|
return;
|
|
220888
220899
|
}
|
|
220889
|
-
|
|
220890
|
-
|
|
220891
|
-
|
|
220892
|
-
const scope = parsedUrl.searchParams.get("scope") || "project";
|
|
220893
|
-
sendJson(res, await buildTeamSnapshot(state.dataDir, state.projectId, scope, state.mode));
|
|
220894
|
-
return;
|
|
220895
|
-
}
|
|
220896
|
-
try {
|
|
220897
|
-
teamInstances.fileLocks.cleanExpired();
|
|
220898
|
-
const agents = teamInstances.registry.listAgents();
|
|
220899
|
-
const locks = teamInstances.fileLocks.listLocks();
|
|
220900
|
-
const tasks = teamInstances.taskManager.list();
|
|
220901
|
-
const available = teamInstances.taskManager.getAvailable();
|
|
220902
|
-
let roles = [];
|
|
220903
|
-
let roleOccupancy = [];
|
|
220904
|
-
let handoffs = [];
|
|
220905
|
-
try {
|
|
220906
|
-
const { getTeamStore: getTeamStore2, isTeamStoreInitialized: isTeamStoreInitialized2 } = await Promise.resolve().then(() => (init_team_store(), team_store_exports));
|
|
220907
|
-
if (isTeamStoreInitialized2()) {
|
|
220908
|
-
const teamStore = getTeamStore2();
|
|
220909
|
-
const projectId2 = state.projectId;
|
|
220910
|
-
roles = teamStore.listRoles(projectId2);
|
|
220911
|
-
roleOccupancy = teamStore.getRoleOccupancy(projectId2);
|
|
220912
|
-
handoffs = teamStore.listHandoffs(projectId2);
|
|
220913
|
-
}
|
|
220914
|
-
} catch {
|
|
220915
|
-
}
|
|
220900
|
+
const parsedUrl = new URL(url2, `http://127.0.0.1:${port}`);
|
|
220901
|
+
if (parsedUrl.pathname === "/api/team") {
|
|
220902
|
+
if (req.method !== "GET") {
|
|
220916
220903
|
sendJson(res, {
|
|
220917
|
-
|
|
220918
|
-
|
|
220919
|
-
|
|
220920
|
-
|
|
220921
|
-
|
|
220922
|
-
|
|
220923
|
-
tasks,
|
|
220924
|
-
availableTasks: available.length,
|
|
220925
|
-
roles,
|
|
220926
|
-
roleOccupancy,
|
|
220927
|
-
handoffs,
|
|
220928
|
-
// Resume data for "Continue this project" area
|
|
220929
|
-
openTasks: tasks.filter((t4) => t4.status === "pending" || t4.status === "in_progress").length,
|
|
220930
|
-
openHandoffs: handoffs.filter((h5) => h5.handoff_status === "open" || h5.handoffStatus === "open").length,
|
|
220931
|
-
totalUnread: agents.reduce((sum, a4) => sum + teamInstances.messageBus.getUnreadCount(a4.id), 0),
|
|
220932
|
-
activeSessions: agents.filter((a4) => a4.status === "active").length
|
|
220933
|
-
});
|
|
220934
|
-
} catch {
|
|
220935
|
-
sendJson(res, { agents: [], activeCount: 0, locks: [], tasks: [], availableTasks: 0, roles: [], roleOccupancy: [], handoffs: [] });
|
|
220904
|
+
status: "error",
|
|
220905
|
+
readOnly: true,
|
|
220906
|
+
error: "Coordination status is read-only",
|
|
220907
|
+
errorCode: "COORDINATION_STATUS_READ_ONLY"
|
|
220908
|
+
}, 405);
|
|
220909
|
+
return;
|
|
220936
220910
|
}
|
|
220911
|
+
const scope = parsedUrl.searchParams.get("scope") || "project";
|
|
220912
|
+
const snapshot = await buildTeamSnapshot(state.dataDir, state.projectId, scope, state.mode);
|
|
220913
|
+
sendJson(res, snapshot, snapshot.status === "error" ? 503 : 200);
|
|
220937
220914
|
return;
|
|
220938
220915
|
}
|
|
220939
220916
|
if (url2.startsWith("/api/")) {
|
|
@@ -220954,13 +220931,12 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
|
|
|
220954
220931
|
server.listen(port, "127.0.0.1", () => {
|
|
220955
220932
|
const url2 = `http://127.0.0.1:${port}`;
|
|
220956
220933
|
const resolvedLabel = projectResolved ? "resolved" : "unresolved";
|
|
220957
|
-
const modeLabel =
|
|
220934
|
+
const modeLabel = "Standalone";
|
|
220958
220935
|
console.error(` Memorix Dashboard [${modeLabel}]`);
|
|
220959
220936
|
console.error(` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
220960
220937
|
console.error(` Mode: ${modeLabel}`);
|
|
220961
220938
|
console.error(` Project: ${projectName} (${projectId}) [${resolvedLabel}]`);
|
|
220962
220939
|
console.error(` Local: ${url2}`);
|
|
220963
|
-
if (isControlPlane) console.error(` MCP: ${url2}/mcp`);
|
|
220964
220940
|
console.error(` Data dir: ${dataDir}`);
|
|
220965
220941
|
console.error(`
|
|
220966
220942
|
Press Ctrl+C to stop
|
|
@@ -261396,7 +261372,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
261396
261372
|
};
|
|
261397
261373
|
const server = existingServer ?? new McpServer({
|
|
261398
261374
|
name: "memorix",
|
|
261399
|
-
version: true ? "1.8.
|
|
261375
|
+
version: true ? "1.8.1" : "1.0.1"
|
|
261400
261376
|
});
|
|
261401
261377
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
261402
261378
|
server.registerTool = ((name, ...args) => {
|
|
@@ -264549,7 +264525,7 @@ ${json4}
|
|
|
264549
264525
|
}
|
|
264550
264526
|
}
|
|
264551
264527
|
console.error(`[memorix] Dashboard staticDir: ${staticDir}`);
|
|
264552
|
-
startDashboard2(projectDir2, portNum, staticDir, project.id, project.name, false,
|
|
264528
|
+
startDashboard2(projectDir2, portNum, staticDir, project.id, project.name, false, project.rootPath, projectResolved).then(() => {
|
|
264553
264529
|
dashboardRunning = true;
|
|
264554
264530
|
}).catch((err) => {
|
|
264555
264531
|
console.error("[memorix] Dashboard error:", err);
|
|
@@ -264891,7 +264867,7 @@ ${lines.join("\n")}` }] };
|
|
|
264891
264867
|
server.registerTool(
|
|
264892
264868
|
"team_task",
|
|
264893
264869
|
{
|
|
264894
|
-
title: "Task
|
|
264870
|
+
title: "Task Status",
|
|
264895
264871
|
description: 'Create, claim, complete, or list tasks in the team task board. Supports dependencies. Action "create": create a task. Action "claim": assign to yourself (atomic, race-safe). Action "complete": mark done with result. Action "list": show tasks.',
|
|
264896
264872
|
inputSchema: {
|
|
264897
264873
|
action: external_exports2.enum(["create", "claim", "complete", "list"]).describe("Operation to perform"),
|
|
@@ -269160,6 +269136,15 @@ var init_serve_http = __esm({
|
|
|
269160
269136
|
return;
|
|
269161
269137
|
}
|
|
269162
269138
|
if (apiPath === "/team") {
|
|
269139
|
+
if (req.method !== "GET") {
|
|
269140
|
+
sendJson2({
|
|
269141
|
+
status: "error",
|
|
269142
|
+
readOnly: true,
|
|
269143
|
+
error: "Coordination status is read-only",
|
|
269144
|
+
errorCode: "COORDINATION_STATUS_READ_ONLY"
|
|
269145
|
+
}, 405);
|
|
269146
|
+
return;
|
|
269147
|
+
}
|
|
269163
269148
|
const { projectId: teamProjectId, dataDir: teamDataDir } = await resolveRequestProject(url2);
|
|
269164
269149
|
const ts2 = await getTeamStore2(teamDataDir);
|
|
269165
269150
|
const scope = url2.searchParams.get("scope") || "project";
|
|
@@ -269224,8 +269209,9 @@ var init_serve_http = __esm({
|
|
|
269224
269209
|
const handoffs = effectiveTeamProjectId ? ts2.listHandoffs(effectiveTeamProjectId) : [];
|
|
269225
269210
|
const openHandoffs = handoffs.filter((handoff) => handoff.status !== "completed").length;
|
|
269226
269211
|
sendJson2({
|
|
269212
|
+
status: "ok",
|
|
269227
269213
|
mode: "control-plane",
|
|
269228
|
-
readOnly:
|
|
269214
|
+
readOnly: true,
|
|
269229
269215
|
scope,
|
|
269230
269216
|
agents: withTier,
|
|
269231
269217
|
// Primary headline number
|
|
@@ -269798,6 +269784,23 @@ var init_serve_http = __esm({
|
|
|
269798
269784
|
}
|
|
269799
269785
|
sendJson2({ error: "Not found" }, 404);
|
|
269800
269786
|
} catch (err) {
|
|
269787
|
+
if (apiPath === "/team") {
|
|
269788
|
+
const scope = url2.searchParams.get("scope") === "global" ? "global" : "project";
|
|
269789
|
+
console.error("[memorix] coordination snapshot unavailable", { status: "error", scope });
|
|
269790
|
+
sendJson2({
|
|
269791
|
+
status: "error",
|
|
269792
|
+
mode: "control-plane",
|
|
269793
|
+
readOnly: true,
|
|
269794
|
+
scope,
|
|
269795
|
+
agents: [],
|
|
269796
|
+
locks: [],
|
|
269797
|
+
tasks: [],
|
|
269798
|
+
handoffs: [],
|
|
269799
|
+
error: "Coordination state unavailable",
|
|
269800
|
+
errorCode: "COORDINATION_STATE_UNAVAILABLE"
|
|
269801
|
+
}, 503);
|
|
269802
|
+
return;
|
|
269803
|
+
}
|
|
269801
269804
|
sendJson2({ error: err instanceof Error ? err.message : "Unknown error" }, 500);
|
|
269802
269805
|
}
|
|
269803
269806
|
}
|
|
@@ -276684,7 +276687,7 @@ var init_dashboard = __esm({
|
|
|
276684
276687
|
}
|
|
276685
276688
|
const cliDir = path45.dirname(fileURLToPath9(import.meta.url));
|
|
276686
276689
|
const staticDir = path45.join(cliDir, "..", "dashboard", "static");
|
|
276687
|
-
await startDashboard2(dataDir, port, staticDir, project.id, project.name, true,
|
|
276690
|
+
await startDashboard2(dataDir, port, staticDir, project.id, project.name, true, project.rootPath, true);
|
|
276688
276691
|
await new Promise(() => {
|
|
276689
276692
|
});
|
|
276690
276693
|
}
|
|
@@ -142,17 +142,21 @@ const i18n = {
|
|
|
142
142
|
noRetentionDesc: 'Store observations to see memory retention scores',
|
|
143
143
|
|
|
144
144
|
// Team -> Coordination
|
|
145
|
-
teamTitle: 'Coordination',
|
|
146
|
-
teamSubtitle: '
|
|
147
|
-
teamNoData: 'No coordination
|
|
148
|
-
teamNoDataHint: '
|
|
145
|
+
teamTitle: 'Coordination Status',
|
|
146
|
+
teamSubtitle: 'Read-only project coordination status',
|
|
147
|
+
teamNoData: 'No coordination status is available',
|
|
148
|
+
teamNoDataHint: 'Coordination state is read-only and comes from the project SQLite store.',
|
|
149
|
+
teamStatusError: 'Coordination status unavailable',
|
|
150
|
+
teamStatusDegraded: 'Coordination status degraded',
|
|
151
|
+
teamStatusErrorDesc: 'The persistent coordination state could not be read. This view has no write actions.',
|
|
152
|
+
teamStatusDegradedDesc: 'Some persistent coordination state could not be read. Values may be incomplete.',
|
|
149
153
|
teamActiveAgents: 'Active Agents',
|
|
150
154
|
teamLockedFiles: 'Locked Files',
|
|
151
155
|
teamTasks: 'Tasks',
|
|
152
156
|
teamAvailable: 'Available',
|
|
153
157
|
teamAgents: 'Agents',
|
|
154
158
|
teamLocks: 'File Locks',
|
|
155
|
-
|
|
159
|
+
teamTaskStatus: 'Task Status',
|
|
156
160
|
// Resume area
|
|
157
161
|
resumeTitle: 'Continue This Project',
|
|
158
162
|
resumeDesc: 'What needs attention right now',
|
|
@@ -282,7 +286,7 @@ const i18n = {
|
|
|
282
286
|
projectUnresolved: 'Unresolved',
|
|
283
287
|
projectUnresolvedDesc: 'No project bound — select a project from the switcher',
|
|
284
288
|
projectResolved: 'Resolved',
|
|
285
|
-
projectScopeProject: 'Project Coordination',
|
|
289
|
+
projectScopeProject: 'Project Coordination Status',
|
|
286
290
|
projectScopeGlobal: 'All Projects',
|
|
287
291
|
projectScopeProjectDesc: 'Agents and tasks coordinated for this project',
|
|
288
292
|
projectScopeGlobalDesc: 'Agents and tasks coordinated across projects',
|
|
@@ -469,8 +473,8 @@ const i18n = {
|
|
|
469
473
|
// Mode banner
|
|
470
474
|
modeStandalone: 'Standalone',
|
|
471
475
|
modeControlPlane: 'Control Plane',
|
|
472
|
-
modeStandaloneHint: 'Standalone dashboard - memory and read-only coordination
|
|
473
|
-
modeControlPlaneHint: 'HTTP control plane - shared MCP access and
|
|
476
|
+
modeStandaloneHint: 'Standalone dashboard - memory and read-only coordination status',
|
|
477
|
+
modeControlPlaneHint: 'HTTP control plane - shared MCP access and read-only coordination status',
|
|
474
478
|
modeBannerProject: 'Project',
|
|
475
479
|
modeBannerMcp: 'MCP',
|
|
476
480
|
|
|
@@ -621,17 +625,21 @@ const i18n = {
|
|
|
621
625
|
noRetentionDesc: '存储观察记录以查看记忆衰减分数',
|
|
622
626
|
|
|
623
627
|
// Team -> 编排协作
|
|
624
|
-
teamTitle: '
|
|
625
|
-
teamSubtitle: '
|
|
626
|
-
teamNoData: '
|
|
627
|
-
teamNoDataHint: '
|
|
628
|
+
teamTitle: '协作状态',
|
|
629
|
+
teamSubtitle: '只读项目协作状态',
|
|
630
|
+
teamNoData: '暂无可用的协作状态',
|
|
631
|
+
teamNoDataHint: '协作状态为只读,并来自项目 SQLite 存储。',
|
|
632
|
+
teamStatusError: '协作状态不可用',
|
|
633
|
+
teamStatusDegraded: '协作状态已降级',
|
|
634
|
+
teamStatusErrorDesc: '无法读取持久协作状态。此视图不提供写入操作。',
|
|
635
|
+
teamStatusDegradedDesc: '部分持久协作状态无法读取,当前数据可能不完整。',
|
|
628
636
|
teamActiveAgents: '活跃 Agent',
|
|
629
637
|
teamLockedFiles: '锁定文件',
|
|
630
638
|
teamTasks: '任务',
|
|
631
639
|
teamAvailable: '可领取',
|
|
632
640
|
teamAgents: 'Agent',
|
|
633
641
|
teamLocks: '文件锁',
|
|
634
|
-
|
|
642
|
+
teamTaskStatus: '任务状态',
|
|
635
643
|
// Resume area
|
|
636
644
|
resumeTitle: '继续这个项目',
|
|
637
645
|
resumeDesc: '当前需要关注的事项',
|
|
@@ -761,7 +769,7 @@ const i18n = {
|
|
|
761
769
|
projectUnresolved: '未绑定',
|
|
762
770
|
projectUnresolvedDesc: '无项目绑定 — 请从切换器选择项目',
|
|
763
771
|
projectResolved: '已绑定',
|
|
764
|
-
projectScopeProject: '
|
|
772
|
+
projectScopeProject: '项目协作状态',
|
|
765
773
|
projectScopeGlobal: '所有项目',
|
|
766
774
|
projectScopeProjectDesc: '当前项目中的 agents 和任务',
|
|
767
775
|
projectScopeGlobalDesc: '所有项目中的 agents 和任务',
|
|
@@ -953,8 +961,8 @@ const i18n = {
|
|
|
953
961
|
// Mode banner
|
|
954
962
|
modeStandalone: '独立模式',
|
|
955
963
|
modeControlPlane: '控制平面',
|
|
956
|
-
modeStandaloneHint: '
|
|
957
|
-
modeControlPlaneHint: 'HTTP 控制平面 - 共享 MCP
|
|
964
|
+
modeStandaloneHint: '独立视图 - 记忆与只读协作状态',
|
|
965
|
+
modeControlPlaneHint: 'HTTP 控制平面 - 共享 MCP 接入与只读协作状态',
|
|
958
966
|
modeBannerProject: '项目',
|
|
959
967
|
modeBannerMcp: 'MCP',
|
|
960
968
|
|
|
@@ -1157,8 +1165,12 @@ async function api(endpoint) {
|
|
|
1157
1165
|
? `/api/${endpoint}${sep}project=${encodeURIComponent(selectedProject)}`
|
|
1158
1166
|
: `/api/${endpoint}`;
|
|
1159
1167
|
const res = await fetch(url);
|
|
1160
|
-
|
|
1161
|
-
|
|
1168
|
+
const payload = await res.json().catch(() => null);
|
|
1169
|
+
if (!res.ok) {
|
|
1170
|
+
if (endpoint.startsWith('team') && payload?.status) return payload;
|
|
1171
|
+
throw new Error(`HTTP ${res.status}`);
|
|
1172
|
+
}
|
|
1173
|
+
return payload;
|
|
1162
1174
|
} catch (err) {
|
|
1163
1175
|
console.error(`API error (${endpoint}):`, err);
|
|
1164
1176
|
return null;
|
|
@@ -4492,7 +4504,10 @@ async function loadTeam() {
|
|
|
4492
4504
|
}
|
|
4493
4505
|
|
|
4494
4506
|
const data = await api('team?scope=' + teamScope);
|
|
4495
|
-
if (!data || data.unavailable) {
|
|
4507
|
+
if (!data || data.unavailable || data.status === 'error' || data.status === 'degraded') {
|
|
4508
|
+
const isDegraded = data?.status === 'degraded';
|
|
4509
|
+
const statusTitle = isDegraded ? t('teamStatusDegraded') : (data?.status === 'error' ? t('teamStatusError') : t('teamNoData'));
|
|
4510
|
+
const statusDescription = isDegraded ? t('teamStatusDegradedDesc') : (data?.status === 'error' ? t('teamStatusErrorDesc') : t('teamNoDataHint'));
|
|
4496
4511
|
container.innerHTML = `
|
|
4497
4512
|
<div class="page-header">
|
|
4498
4513
|
<h1 class="page-title">${t('teamTitle')}</h1>
|
|
@@ -4501,10 +4516,9 @@ async function loadTeam() {
|
|
|
4501
4516
|
<div class="panel">
|
|
4502
4517
|
<div class="panel-body" style="text-align:center;padding:48px;">
|
|
4503
4518
|
<div style="font-size:36px;margin-bottom:12px;"><span class="iconify" data-icon="lucide:users" style="font-size:36px;"></span></div>
|
|
4504
|
-
<div style="font-size:16px;font-weight:600;color:var(--text-primary);margin-bottom:8px;">${
|
|
4519
|
+
<div style="font-size:16px;font-weight:600;color:var(--text-primary);margin-bottom:8px;">${statusTitle}</div>
|
|
4505
4520
|
<div style="font-size:13px;color:var(--text-muted);max-width:480px;margin:0 auto;line-height:1.6;">
|
|
4506
|
-
${
|
|
4507
|
-
<code style="background:var(--bg-surface);padding:4px 10px;border-radius:6px;margin-top:8px;display:inline-block;font-size:12px;">memorix orchestrate · memorix team status · memorix task list</code>
|
|
4521
|
+
${statusDescription}<br>
|
|
4508
4522
|
</div>
|
|
4509
4523
|
</div>
|
|
4510
4524
|
</div>
|
|
@@ -4763,7 +4777,7 @@ async function loadTeam() {
|
|
|
4763
4777
|
|
|
4764
4778
|
<div class="panel">
|
|
4765
4779
|
<div class="panel-header">
|
|
4766
|
-
<span class="panel-title">${t('
|
|
4780
|
+
<span class="panel-title">${t('teamTaskStatus')}</span>
|
|
4767
4781
|
<span class="team-panel-count">${data.availableTasks || 0} ${t('teamAvailableToClaim')}</span>
|
|
4768
4782
|
</div>
|
|
4769
4783
|
<div class="panel-body">
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
</svg>
|
|
136
136
|
<span class="nav-label">Sessions</span>
|
|
137
137
|
</button>
|
|
138
|
-
<button class="nav-btn" data-page="team" title="Coordination" aria-label="Coordination">
|
|
138
|
+
<button class="nav-btn" data-page="team" title="Coordination Status" aria-label="Coordination Status">
|
|
139
139
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
140
140
|
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
|
|
141
141
|
<circle cx="9" cy="7" r="4"/>
|
package/dist/index.d.ts
CHANGED
|
@@ -479,7 +479,7 @@ type ToolProfile = 'micro' | 'lite' | 'team' | 'full';
|
|
|
479
479
|
* Create and configure the Memorix MCP Server.
|
|
480
480
|
*/
|
|
481
481
|
/** Optional shared TeamStore — passed by serve-http so all sessions share state */
|
|
482
|
-
interface
|
|
482
|
+
interface SharedTeamStore {
|
|
483
483
|
teamStore: TeamStore;
|
|
484
484
|
}
|
|
485
485
|
interface CreateMemorixServerOptions {
|
|
@@ -500,7 +500,7 @@ interface CreateMemorixServerOptions {
|
|
|
500
500
|
*/
|
|
501
501
|
projectBinding?: ProjectBindingController;
|
|
502
502
|
}
|
|
503
|
-
declare function createMemorixServer(cwd?: string, existingServer?: McpServer, sharedTeam?:
|
|
503
|
+
declare function createMemorixServer(cwd?: string, existingServer?: McpServer, sharedTeam?: SharedTeamStore, options?: CreateMemorixServerOptions): Promise<{
|
|
504
504
|
server: McpServer;
|
|
505
505
|
graphManager: KnowledgeGraphManager;
|
|
506
506
|
projectId: string;
|