@omgbase/core 0.5.0 → 0.6.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/dist/src/mcp/server.js
CHANGED
|
@@ -809,11 +809,11 @@ export function buildServer(ctx) {
|
|
|
809
809
|
}
|
|
810
810
|
});
|
|
811
811
|
server.registerTool("docs_move", {
|
|
812
|
-
description: "Rename a document to a new repo-relative path; block identity and history are preserved
|
|
812
|
+
description: "Rename a document to a new repo-relative path; block identity and history are preserved, and the inbound links FOLLOW it: every link written against the old path (Markdown links/images, wikilinks, bare-path inline fields — anchors, link text, titles and code spans preserved, absolute vs relative style kept) is rewritten to the new path in the same call as one CAS-checked changeset, so a move never leaves the graph broken. Fails path_taken if the destination exists. The result carries `retargeted` (the touched blocks/docs) and `dangling` — what could NOT be rewritten, i.e. frontmatter relations (block null; fix with docs_set_meta). Pass `retarget_inbound:false` to opt out for the rarer intent that the old path become unbound: the links are left as written, listed in `dangling` ({doc, path, block, target, anchor, field?} per occurrence) and reported by links_stale (their edges become `phantom:<old path>`); links already written against the new path start resolving to this doc either way. dry_run:true validates and returns the plan — `dangling`, `retargeted`, and the per-file `diffs` (the old path emptied, the new path filled, plus the rewritten sources) — without renaming or committing.",
|
|
813
813
|
inputSchema: { doc: z.string(), to_path: z.string(), retarget_inbound: z.boolean().optional(), dry_run: z.boolean().optional(), ...REPO_ARG },
|
|
814
814
|
}, async (args) => {
|
|
815
815
|
try {
|
|
816
|
-
return docResult(docsMove(store, docCtx(repoScope(args.repo), args.dry_run), args.doc, args.to_path, { retargetInbound: args.retarget_inbound
|
|
816
|
+
return docResult(docsMove(store, docCtx(repoScope(args.repo), args.dry_run), args.doc, args.to_path, { retargetInbound: args.retarget_inbound !== false }), args.dry_run);
|
|
817
817
|
}
|
|
818
818
|
catch (e) {
|
|
819
819
|
return fail(e);
|
|
@@ -40,22 +40,30 @@ export interface DocOpResult {
|
|
|
40
40
|
}
|
|
41
41
|
export interface DocMoveOptions {
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
43
|
+
* Rewrite the inbound links that named the OLD path so they point at the new
|
|
44
|
+
* one — a destination-aware rewrite (anchors, link text, titles, and code
|
|
45
45
|
* spans preserved; absolute/relative style kept) applied as a CAS-checked
|
|
46
|
-
* `update` per source block in one follow-up api changeset.
|
|
47
|
-
*
|
|
46
|
+
* `update` per source block in one follow-up api changeset. **Default `true`**
|
|
47
|
+
* (spec/mutate 1.3): a move means "same document, new place", so the authored
|
|
48
|
+
* links follow it; pass `false` for the rarer intent that the old path become
|
|
49
|
+
* unbound. Frontmatter-level relations are never rewritten (reported in
|
|
50
|
+
* `dangling`).
|
|
48
51
|
*/
|
|
49
52
|
retargetInbound?: boolean;
|
|
50
53
|
}
|
|
51
54
|
export interface DocMoveResult extends DocOpResult {
|
|
52
55
|
/**
|
|
53
56
|
* Inbound links still pointing at the OLD path after this call — the source
|
|
54
|
-
* blocks `links_stale` will now report (
|
|
55
|
-
*
|
|
57
|
+
* blocks `links_stale` will now report (with the default retarget: only the
|
|
58
|
+
* frontmatter relations, which are never rewritten). Computed from the open
|
|
59
|
+
* edge index before the move.
|
|
56
60
|
*/
|
|
57
61
|
dangling: InboundLink[];
|
|
58
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* The source blocks rewritten and the docs re-ingested (empty lists when the
|
|
64
|
+
* rewrite ran but only frontmatter relations linked in); `null` when the
|
|
65
|
+
* retarget was opted out (`retargetInbound: false`) or nothing linked in.
|
|
66
|
+
*/
|
|
59
67
|
retargeted: {
|
|
60
68
|
blocks: string[];
|
|
61
69
|
docs: string[];
|
|
@@ -68,8 +76,10 @@ export declare function docsCreate(store: Store, ctx: DocOpContext, path: string
|
|
|
68
76
|
* index follows the path, not the identity: links written against the OLD path
|
|
69
77
|
* now dangle (their open edges are re-pointed at `phantom:<old>`, exactly what
|
|
70
78
|
* re-extracting the source would produce, so `links_stale` sees them), and
|
|
71
|
-
* phantom edges already written against the NEW path are adopted.
|
|
72
|
-
*
|
|
79
|
+
* phantom edges already written against the NEW path are adopted. By default
|
|
80
|
+
* the dangling inbound links are then rewritten to the new path in one
|
|
81
|
+
* follow-up changeset (spec/mutate 1.3); `retargetInbound: false` leaves them
|
|
82
|
+
* as written and the result lists them.
|
|
73
83
|
*/
|
|
74
84
|
export declare function docsMove(store: Store, ctx: DocOpContext, docRef: string, toPath: string, opts?: DocMoveOptions): DocMoveResult;
|
|
75
85
|
/** docs_delete: mark a document deleted and remove its file (resurrection-poolable). */
|
package/dist/src/mutate/docs.js
CHANGED
|
@@ -60,10 +60,13 @@ export function docsCreate(store, ctx, path, markdown, frontmatter) {
|
|
|
60
60
|
* index follows the path, not the identity: links written against the OLD path
|
|
61
61
|
* now dangle (their open edges are re-pointed at `phantom:<old>`, exactly what
|
|
62
62
|
* re-extracting the source would produce, so `links_stale` sees them), and
|
|
63
|
-
* phantom edges already written against the NEW path are adopted.
|
|
64
|
-
*
|
|
63
|
+
* phantom edges already written against the NEW path are adopted. By default
|
|
64
|
+
* the dangling inbound links are then rewritten to the new path in one
|
|
65
|
+
* follow-up changeset (spec/mutate 1.3); `retargetInbound: false` leaves them
|
|
66
|
+
* as written and the result lists them.
|
|
65
67
|
*/
|
|
66
68
|
export function docsMove(store, ctx, docRef, toPath, opts = {}) {
|
|
69
|
+
const retargetInbound = opts.retargetInbound !== false;
|
|
67
70
|
const info = findDocByRef(store, ctx.repoId, docRef);
|
|
68
71
|
if (!info)
|
|
69
72
|
throw new MutationError("doc_missing", `no document ${docRef}`);
|
|
@@ -79,7 +82,7 @@ export function docsMove(store, ctx, docRef, toPath, opts = {}) {
|
|
|
79
82
|
const content = docStore.read(info.path) ?? "";
|
|
80
83
|
const diffs = { [info.path]: { before: content, after: "" }, [toRel]: { before: "", after: content } };
|
|
81
84
|
const planned = { docId: info.docId, path: toRel, committed: false, diffs };
|
|
82
|
-
if (!
|
|
85
|
+
if (!retargetInbound || inbound.length === 0)
|
|
83
86
|
return { ...planned, dangling: inbound, retargeted: null };
|
|
84
87
|
const plan = planInboundRetarget(store, info.docId, info.path, toRel, inbound);
|
|
85
88
|
if (plan.ops.length > 0) {
|
|
@@ -134,7 +137,7 @@ export function docsMove(store, ctx, docRef, toPath, opts = {}) {
|
|
|
134
137
|
}
|
|
135
138
|
return { docId: info.docId, path: toRel, committed: true };
|
|
136
139
|
});
|
|
137
|
-
if (!
|
|
140
|
+
if (!retargetInbound || inbound.length === 0)
|
|
138
141
|
return { ...moved, dangling: inbound, retargeted: null };
|
|
139
142
|
// Rewrite the dangling links block by block (one coalesced update per block,
|
|
140
143
|
// CAS on the block's current hash) and apply as one changeset; the re-ingest
|
|
@@ -6,9 +6,9 @@ export declare const SPEC_VERSIONS: {
|
|
|
6
6
|
readonly properties: "1.1";
|
|
7
7
|
readonly graph: "1.1";
|
|
8
8
|
readonly search: "1.2";
|
|
9
|
-
readonly mutate: "1.
|
|
9
|
+
readonly mutate: "1.3";
|
|
10
10
|
readonly sync: "1.3";
|
|
11
11
|
readonly surface: "1.4";
|
|
12
|
-
readonly cli: "1.
|
|
12
|
+
readonly cli: "1.2";
|
|
13
13
|
};
|
|
14
14
|
export type SpecName = keyof typeof SPEC_VERSIONS;
|