API: adding one memory is POST /api/v2/memories with its status at
GET /api/v2/memories/additions/{request_id}; /api/v1/memory-notes is
removed. Error codes memory_note_* become memory_add_*, contracts types
MemoryAddInput/MemoryAddReceipt, broker /memories, MCP MemHub_write and
the web composer follow. Stored names (memory_note_requests,
one-memory-manual, direct_memory_note) stay. /api/v2/memory-library
takes an optional scene filter.
CLI:
- No plan files. memories add/add-status, models add/test/receipt and
sources connect execute directly; async receipts stay.
- One --yes, only for irreversible operations (memories delete, models
remove, delete-data, backup restore, graph-width rebuild); without it
they preview and exit 0. --confirm is a hidden alias.
- Removed notes, calls, setup plan, sources import, models
plan/configure/probe*, and the unreachable processing, extraction and
import-file commands, with their dead allow-list entries.
- memories list gets --scene/--source/--query; show/update/delete take
--kind/--variant (and --task). All memories JSON is schema_version 2.
- Fixes from the CLI review: global --data-dir, real
--confirm-overrides and help that matches init, server failures exit 1
not 2, catalog exit codes match, JSON errors on stdout, bad filters are
rejected instead of "busy", write submit prints its request_id for
retries, recall labels raw excerpts, stop says it disables login
auto-start, backup help says memories are not included yet.
- Hidden aliases: path -> scan-roots, task -> write status,
graph width -> graph-width, init --source -> sources connect.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
94 lines
2.8 KiB
TypeScript
94 lines
2.8 KiB
TypeScript
/**
|
||
* `memhub graph-width`: the user's decision when the embedding width changed
|
||
* and the memory graph no longer matches it (`POST /api/v1/graph-width`).
|
||
*
|
||
* `keep_existing` and `export_first` change nothing irreversible and run
|
||
* directly. `rebuild_with_new` archives the current graph and rebuilds it, so
|
||
* the CLI asks for `--yes` before sending it.
|
||
*/
|
||
|
||
import { parseGraphWidthDecisionReceipt } from "@one-memory/operations";
|
||
import type { CoreOperations } from "./core-operations.js";
|
||
import { PRODUCT } from "./version.js";
|
||
|
||
export const GRAPH_WIDTH_DECISIONS = [
|
||
"keep_existing",
|
||
"rebuild_with_new",
|
||
"export_first",
|
||
] as const;
|
||
export type GraphWidthDecision = (typeof GRAPH_WIDTH_DECISIONS)[number];
|
||
|
||
/** The one decision that cannot be taken back. */
|
||
export function graphWidthDecisionIsDestructive(
|
||
decision: GraphWidthDecision,
|
||
): boolean {
|
||
return decision === "rebuild_with_new";
|
||
}
|
||
|
||
export type GraphWidthDocument =
|
||
| {
|
||
schema_version: 1;
|
||
product: string;
|
||
command: "graph-width";
|
||
state: "committed";
|
||
decision: GraphWidthDecision;
|
||
receipt: Record<string, unknown>;
|
||
}
|
||
| {
|
||
schema_version: 1;
|
||
product: string;
|
||
command: "graph-width";
|
||
state: "rejected" | "unknown";
|
||
decision: GraphWidthDecision;
|
||
code: string;
|
||
};
|
||
|
||
export async function decideGraphWidth(
|
||
decision: GraphWidthDecision,
|
||
operations: CoreOperations,
|
||
): Promise<GraphWidthDocument> {
|
||
const base = {
|
||
schema_version: 1 as const,
|
||
product: PRODUCT,
|
||
command: "graph-width" as const,
|
||
decision,
|
||
};
|
||
const result = await operations.post<unknown>("/api/v1/graph-width", {
|
||
decision,
|
||
});
|
||
if (result.state !== "committed") {
|
||
return { ...base, state: result.state, code: result.code };
|
||
}
|
||
const receipt = parseGraphWidthDecisionReceipt(result.data);
|
||
if (receipt === null) {
|
||
return { ...base, state: "unknown", code: "graph_width_receipt_invalid" };
|
||
}
|
||
return {
|
||
...base,
|
||
state: "committed",
|
||
receipt: {
|
||
archived_path: receipt.archived_path ?? null,
|
||
exported_path: receipt.exported_path ?? null,
|
||
mismatch: receipt.mismatch ?? null,
|
||
},
|
||
};
|
||
}
|
||
|
||
export function graphWidthExitCode(document: GraphWidthDocument): number {
|
||
return document.state === "committed" ? 0 : 1;
|
||
}
|
||
|
||
export function renderGraphWidthText(document: GraphWidthDocument): string {
|
||
if (document.state === "committed") {
|
||
const lines = [`已执行图谱宽度决定:${document.decision}`];
|
||
if (document.receipt.exported_path) {
|
||
lines.push(`导出:${document.receipt.exported_path}`);
|
||
}
|
||
if (document.receipt.archived_path) {
|
||
lines.push(`旧图谱已归档:${document.receipt.archived_path}`);
|
||
}
|
||
return `${lines.join("\n")}\n`;
|
||
}
|
||
return `图谱宽度决定未完成:${document.state}(${document.code})\n`;
|
||
}
|