@gmickel/gno 1.30.7 → 1.32.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 +6 -5
- package/assets/skill/SKILL.md +25 -0
- package/assets/skill/mcp-reference.md +6 -0
- package/browser-extension/artifacts/{gno-browser-clipper-v1.30.7.zip → gno-browser-clipper-v1.32.0.zip} +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.32.0.zip.sha256 +1 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/package.json +1 -1
- package/spec/cli.md +19 -0
- package/spec/db/schema.sql +55 -0
- package/spec/mcp.md +176 -11
- package/spec/output-schemas/file-refactor-apply-result.schema.json +305 -0
- package/spec/output-schemas/file-refactor-preview.schema.json +393 -0
- package/spec/output-schemas/section-target-create-result.schema.json +20 -0
- package/spec/output-schemas/section-target-resolve-result.schema.json +194 -0
- package/spec/output-schemas/section-target.schema.json +118 -0
- package/spec/output-schemas/section.schema.json +113 -0
- package/src/core/document-capabilities.ts +13 -0
- package/src/core/file-ops.ts +129 -1
- package/src/core/file-refactor-adapter.ts +329 -0
- package/src/core/file-refactor-apply-edits.ts +61 -0
- package/src/core/file-refactor-apply-fs.ts +512 -0
- package/src/core/file-refactor-apply-safety.ts +340 -0
- package/src/core/file-refactor-apply-validate.ts +401 -0
- package/src/core/file-refactor-contract.ts +486 -0
- package/src/core/file-refactor-destination.ts +123 -0
- package/src/core/file-refactor-from-snapshot.ts +148 -0
- package/src/core/file-refactor-journal-port.ts +150 -0
- package/src/core/file-refactor-journal.ts +347 -0
- package/src/core/file-refactor-paths.ts +60 -0
- package/src/core/file-refactor-plan-classify.ts +208 -0
- package/src/core/file-refactor-plan-validate.ts +169 -0
- package/src/core/file-refactor-planner-types.ts +62 -0
- package/src/core/file-refactor-planner.ts +423 -0
- package/src/core/file-refactor-resolve.ts +280 -0
- package/src/core/file-refactor-service.ts +468 -0
- package/src/core/file-refactors.ts +84 -56
- package/src/core/link-destination-parse.ts +275 -0
- package/src/core/link-inventory-markdown.ts +454 -0
- package/src/core/link-inventory-opaque.ts +244 -0
- package/src/core/link-inventory-types.ts +47 -0
- package/src/core/link-inventory.ts +182 -0
- package/src/core/link-relevance.ts +150 -0
- package/src/core/section-parse.ts +187 -0
- package/src/core/section-target-link.ts +154 -0
- package/src/core/section-target-resolve.ts +351 -0
- package/src/core/section-target-transport.ts +519 -0
- package/src/core/section-target.ts +263 -0
- package/src/core/sections.ts +60 -115
- package/src/mcp/AGENTS.md +1 -0
- package/src/mcp/CLAUDE.md +1 -0
- package/src/mcp/http-egress.ts +1 -0
- package/src/mcp/tools/index.ts +37 -17
- package/src/mcp/tools/sections.ts +512 -0
- package/src/mcp/tools/workspace-write.ts +215 -97
- package/src/sdk/client.ts +238 -116
- package/src/sdk/index.ts +12 -0
- package/src/sdk/types.ts +61 -3
- package/src/serve/file-refactor-http.ts +239 -0
- package/src/serve/public/components/RefactorImpactPreview.tsx +227 -0
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/lib/section-links.ts +189 -0
- package/src/serve/public/pages/DocView.tsx +395 -77
- package/src/serve/routes/api.ts +191 -104
- package/src/serve/routes/section-targets.ts +221 -0
- package/src/serve/server.ts +34 -0
- package/src/store/migrations/026-file-refactor-recovery-journal.ts +72 -0
- package/src/store/migrations/index.ts +2 -0
- package/src/store/sqlite/adapter.ts +452 -0
- package/src/store/sqlite/file-refactor-journal-store.ts +275 -0
- package/src/store/types.ts +84 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.30.7.zip.sha256 +0 -1
package/src/sdk/client.ts
CHANGED
|
@@ -34,10 +34,12 @@ import type {
|
|
|
34
34
|
GnoIndexResult,
|
|
35
35
|
GnoIndexStatus,
|
|
36
36
|
GnoListOptions,
|
|
37
|
+
GnoMoveNoteApplyOptions,
|
|
37
38
|
GnoMoveNoteOptions,
|
|
38
39
|
GnoMultiGetOptions,
|
|
39
40
|
GnoQueryOptions,
|
|
40
41
|
GnoRefactorNoteResult,
|
|
42
|
+
GnoRenameNoteApplyOptions,
|
|
41
43
|
GnoRenameNoteOptions,
|
|
42
44
|
GnoSearchOptions,
|
|
43
45
|
GnoUpdateOptions,
|
|
@@ -47,6 +49,10 @@ import type {
|
|
|
47
49
|
KnowledgeImpactInput,
|
|
48
50
|
KnowledgeImpactResult,
|
|
49
51
|
ListKnowledgeChangesInput,
|
|
52
|
+
SectionTargetCreateResult,
|
|
53
|
+
SectionTargetCreateSelector,
|
|
54
|
+
SectionTargetResolveResult,
|
|
55
|
+
SectionTargetV1,
|
|
50
56
|
} from "./types";
|
|
51
57
|
|
|
52
58
|
import {
|
|
@@ -82,20 +88,23 @@ import { writeCapturePlanFile } from "../core/capture-write";
|
|
|
82
88
|
import { projectCollectionEgressPolicy } from "../core/collection-egress-policy-projection";
|
|
83
89
|
import { CollectionEgressPolicyService } from "../core/collection-egress-policy-service";
|
|
84
90
|
import { applyConfigChange } from "../core/config-mutation";
|
|
91
|
+
import { getDocumentCapabilities } from "../core/document-capabilities";
|
|
85
92
|
import { EgressAuditService } from "../core/egress-audit";
|
|
86
93
|
import { authorizeCurrentEgress } from "../core/egress-authorization";
|
|
94
|
+
import { atomicWrite, copyFilePath, createFolderPath } from "../core/file-ops";
|
|
87
95
|
import {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
} from "../core/file-ops";
|
|
93
|
-
import {
|
|
96
|
+
applyCanonicalFileRefactor,
|
|
97
|
+
assertFileRefactorSyncConverged,
|
|
98
|
+
buildCanonicalRefactorPlan,
|
|
99
|
+
buildDurableFileRefactorApplyDeps,
|
|
94
100
|
buildRefactorWarnings,
|
|
101
|
+
parseRefactorApplyConfirmation,
|
|
95
102
|
planCreateFolder,
|
|
96
103
|
planDuplicateRefactor,
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
resolveMoveTarget,
|
|
105
|
+
resolveRenameTarget,
|
|
106
|
+
type FileRefactorApplyResult,
|
|
107
|
+
type FileRefactorPreviewPlan,
|
|
99
108
|
} from "../core/file-refactors";
|
|
100
109
|
import { resolveEffectiveIndex } from "../core/indexed-reference";
|
|
101
110
|
import {
|
|
@@ -122,7 +131,17 @@ import {
|
|
|
122
131
|
RETRIEVAL_TRACE_METADATA,
|
|
123
132
|
type RetrievalTraceSession,
|
|
124
133
|
} from "../core/retrieval-trace-session";
|
|
125
|
-
import {
|
|
134
|
+
import {
|
|
135
|
+
CANONICAL_URI_EXCEEDS_TRANSPORT_BOUNDS,
|
|
136
|
+
createSectionTarget as createSectionTargetCore,
|
|
137
|
+
extractSections,
|
|
138
|
+
isTransportBoundedCanonicalUri,
|
|
139
|
+
parseSectionTargetCreateSelector,
|
|
140
|
+
parseSectionTargetV1,
|
|
141
|
+
projectSectionTargetCreateResult,
|
|
142
|
+
projectSectionTargetResolveResult,
|
|
143
|
+
resolveSectionTarget as resolveSectionTargetCore,
|
|
144
|
+
} from "../core/sections";
|
|
126
145
|
import { normalizeStructuredQueryInput } from "../core/structured-query";
|
|
127
146
|
import { parseAndValidateTagFilter } from "../core/tags";
|
|
128
147
|
import {
|
|
@@ -320,6 +339,52 @@ class GnoClientImpl implements GnoClient {
|
|
|
320
339
|
return filtered;
|
|
321
340
|
}
|
|
322
341
|
|
|
342
|
+
private requireRefactorApplyConfirmation(options: {
|
|
343
|
+
schemaVersion?: unknown;
|
|
344
|
+
planDigest?: unknown;
|
|
345
|
+
confirmation?: unknown;
|
|
346
|
+
}) {
|
|
347
|
+
const parsed = parseRefactorApplyConfirmation(options);
|
|
348
|
+
if ("error" in parsed) {
|
|
349
|
+
throw sdkError("VALIDATION", parsed.message);
|
|
350
|
+
}
|
|
351
|
+
return parsed;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
private async prepareRefactorSource(ref: string) {
|
|
355
|
+
const doc = await getDocumentByRef(this.store, this.config, ref, {});
|
|
356
|
+
const stored = await this.store.getDocumentByUri(doc.uri);
|
|
357
|
+
if (!stored.ok || !stored.value) {
|
|
358
|
+
throw sdkError("NOT_FOUND", "Document not found");
|
|
359
|
+
}
|
|
360
|
+
const storedDoc = stored.value;
|
|
361
|
+
const collection = this.getCollections(storedDoc.collection)[0];
|
|
362
|
+
if (!collection) {
|
|
363
|
+
throw sdkError(
|
|
364
|
+
"VALIDATION",
|
|
365
|
+
`Collection not found: ${storedDoc.collection}`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
const capabilities = getDocumentCapabilities({
|
|
369
|
+
sourceExt: storedDoc.sourceExt,
|
|
370
|
+
sourceMime: storedDoc.sourceMime,
|
|
371
|
+
contentAvailable: storedDoc.mirrorHash !== null,
|
|
372
|
+
recordKey: storedDoc.recordKey,
|
|
373
|
+
});
|
|
374
|
+
if (!capabilities.editable) {
|
|
375
|
+
throw sdkError(
|
|
376
|
+
"VALIDATION",
|
|
377
|
+
capabilities.reason ?? "Document is read-only in place."
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
return {
|
|
381
|
+
storedDoc,
|
|
382
|
+
collection,
|
|
383
|
+
sourceFullPath: `${collection.path}/${storedDoc.relPath}`,
|
|
384
|
+
editable: capabilities.editable,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
323
388
|
private async createRuntimePorts(options: {
|
|
324
389
|
embed?: boolean;
|
|
325
390
|
expand?: boolean;
|
|
@@ -1643,125 +1708,126 @@ class GnoClientImpl implements GnoClient {
|
|
|
1643
1708
|
};
|
|
1644
1709
|
}
|
|
1645
1710
|
|
|
1646
|
-
async
|
|
1711
|
+
async previewRenameNote(
|
|
1647
1712
|
options: GnoRenameNoteOptions
|
|
1648
|
-
): Promise<
|
|
1713
|
+
): Promise<FileRefactorPreviewPlan> {
|
|
1649
1714
|
this.assertOpen();
|
|
1650
|
-
const
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
{}
|
|
1655
|
-
);
|
|
1656
|
-
const stored = await this.store.getDocumentByUri(doc.uri);
|
|
1657
|
-
if (!stored.ok || !stored.value) {
|
|
1658
|
-
throw sdkError("NOT_FOUND", "Document not found");
|
|
1659
|
-
}
|
|
1660
|
-
const storedDoc = stored.value;
|
|
1661
|
-
const collection = this.getCollections(storedDoc.collection)[0];
|
|
1662
|
-
if (!collection) {
|
|
1663
|
-
throw sdkError(
|
|
1664
|
-
"VALIDATION",
|
|
1665
|
-
`Collection not found: ${storedDoc.collection}`
|
|
1666
|
-
);
|
|
1667
|
-
}
|
|
1668
|
-
const plan = planRenameRefactor({
|
|
1669
|
-
collection: collection.name,
|
|
1670
|
-
currentRelPath: storedDoc.relPath,
|
|
1715
|
+
const prepared = await this.prepareRefactorSource(options.ref);
|
|
1716
|
+
const target = resolveRenameTarget({
|
|
1717
|
+
collection: prepared.collection.name,
|
|
1718
|
+
currentRelPath: prepared.storedDoc.relPath,
|
|
1671
1719
|
nextName: options.name,
|
|
1672
1720
|
});
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1721
|
+
return buildCanonicalRefactorPlan({
|
|
1722
|
+
operation: "rename",
|
|
1723
|
+
doc: prepared.storedDoc,
|
|
1724
|
+
collection: prepared.collection,
|
|
1725
|
+
sourceFullPath: prepared.sourceFullPath,
|
|
1726
|
+
target,
|
|
1727
|
+
store: this.store,
|
|
1728
|
+
sourceEditable: prepared.editable,
|
|
1729
|
+
});
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
async previewMoveNote(
|
|
1733
|
+
options: GnoMoveNoteOptions
|
|
1734
|
+
): Promise<FileRefactorPreviewPlan> {
|
|
1735
|
+
this.assertOpen();
|
|
1736
|
+
const prepared = await this.prepareRefactorSource(options.ref);
|
|
1737
|
+
const target = resolveMoveTarget({
|
|
1738
|
+
collection: prepared.collection.name,
|
|
1739
|
+
currentRelPath: prepared.storedDoc.relPath,
|
|
1740
|
+
folderPath: options.folderPath,
|
|
1741
|
+
nextName: options.name,
|
|
1742
|
+
});
|
|
1743
|
+
return buildCanonicalRefactorPlan({
|
|
1744
|
+
operation: "move",
|
|
1745
|
+
doc: prepared.storedDoc,
|
|
1746
|
+
collection: prepared.collection,
|
|
1747
|
+
sourceFullPath: prepared.sourceFullPath,
|
|
1748
|
+
target,
|
|
1749
|
+
store: this.store,
|
|
1750
|
+
sourceEditable: prepared.editable,
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
async renameNote(
|
|
1755
|
+
options: GnoRenameNoteApplyOptions
|
|
1756
|
+
): Promise<FileRefactorApplyResult> {
|
|
1757
|
+
this.assertOpen();
|
|
1758
|
+
const confirmation = this.requireRefactorApplyConfirmation(options);
|
|
1759
|
+
const prepared = await this.prepareRefactorSource(options.ref);
|
|
1760
|
+
const target = resolveRenameTarget({
|
|
1761
|
+
collection: prepared.collection.name,
|
|
1762
|
+
currentRelPath: prepared.storedDoc.relPath,
|
|
1763
|
+
nextName: options.name,
|
|
1764
|
+
});
|
|
1765
|
+
const plan = await buildCanonicalRefactorPlan({
|
|
1766
|
+
operation: "rename",
|
|
1767
|
+
doc: prepared.storedDoc,
|
|
1768
|
+
collection: prepared.collection,
|
|
1769
|
+
sourceFullPath: prepared.sourceFullPath,
|
|
1770
|
+
target,
|
|
1771
|
+
store: this.store,
|
|
1772
|
+
sourceEditable: prepared.editable,
|
|
1773
|
+
});
|
|
1774
|
+
const apply = await applyCanonicalFileRefactor({
|
|
1775
|
+
plan,
|
|
1776
|
+
confirmation,
|
|
1777
|
+
deps: buildDurableFileRefactorApplyDeps({
|
|
1778
|
+
collection: prepared.collection,
|
|
1779
|
+
store: this.store,
|
|
1780
|
+
syncAfterCommit: async () => {
|
|
1781
|
+
const syncResult = await defaultSyncService.syncCollection(
|
|
1782
|
+
prepared.collection,
|
|
1783
|
+
this.store,
|
|
1784
|
+
withContentTypeRules({ runUpdateCmd: false }, this.config)
|
|
1785
|
+
);
|
|
1786
|
+
assertFileRefactorSyncConverged(syncResult);
|
|
1699
1787
|
},
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1788
|
+
}),
|
|
1789
|
+
});
|
|
1790
|
+
return apply;
|
|
1703
1791
|
}
|
|
1704
1792
|
|
|
1705
|
-
async moveNote(
|
|
1793
|
+
async moveNote(
|
|
1794
|
+
options: GnoMoveNoteApplyOptions
|
|
1795
|
+
): Promise<FileRefactorApplyResult> {
|
|
1706
1796
|
this.assertOpen();
|
|
1707
|
-
const
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
);
|
|
1713
|
-
const stored = await this.store.getDocumentByUri(doc.uri);
|
|
1714
|
-
if (!stored.ok || !stored.value) {
|
|
1715
|
-
throw sdkError("NOT_FOUND", "Document not found");
|
|
1716
|
-
}
|
|
1717
|
-
const storedDoc = stored.value;
|
|
1718
|
-
const collection = this.getCollections(storedDoc.collection)[0];
|
|
1719
|
-
if (!collection) {
|
|
1720
|
-
throw sdkError(
|
|
1721
|
-
"VALIDATION",
|
|
1722
|
-
`Collection not found: ${storedDoc.collection}`
|
|
1723
|
-
);
|
|
1724
|
-
}
|
|
1725
|
-
const plan = planMoveRefactor({
|
|
1726
|
-
collection: collection.name,
|
|
1727
|
-
currentRelPath: storedDoc.relPath,
|
|
1797
|
+
const confirmation = this.requireRefactorApplyConfirmation(options);
|
|
1798
|
+
const prepared = await this.prepareRefactorSource(options.ref);
|
|
1799
|
+
const target = resolveMoveTarget({
|
|
1800
|
+
collection: prepared.collection.name,
|
|
1801
|
+
currentRelPath: prepared.storedDoc.relPath,
|
|
1728
1802
|
folderPath: options.folderPath,
|
|
1729
1803
|
nextName: options.name,
|
|
1730
1804
|
});
|
|
1731
|
-
const
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
this.store,
|
|
1738
|
-
|
|
1739
|
-
);
|
|
1740
|
-
const
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
(entry) => entry.linkType === "wiki"
|
|
1754
|
-
).length,
|
|
1755
|
-
markdownLinks: linksResult.value.filter(
|
|
1756
|
-
(entry) => entry.linkType === "markdown"
|
|
1757
|
-
).length,
|
|
1805
|
+
const plan = await buildCanonicalRefactorPlan({
|
|
1806
|
+
operation: "move",
|
|
1807
|
+
doc: prepared.storedDoc,
|
|
1808
|
+
collection: prepared.collection,
|
|
1809
|
+
sourceFullPath: prepared.sourceFullPath,
|
|
1810
|
+
target,
|
|
1811
|
+
store: this.store,
|
|
1812
|
+
sourceEditable: prepared.editable,
|
|
1813
|
+
});
|
|
1814
|
+
const apply = await applyCanonicalFileRefactor({
|
|
1815
|
+
plan,
|
|
1816
|
+
confirmation,
|
|
1817
|
+
deps: buildDurableFileRefactorApplyDeps({
|
|
1818
|
+
collection: prepared.collection,
|
|
1819
|
+
store: this.store,
|
|
1820
|
+
syncAfterCommit: async () => {
|
|
1821
|
+
const syncResult = await defaultSyncService.syncCollection(
|
|
1822
|
+
prepared.collection,
|
|
1823
|
+
this.store,
|
|
1824
|
+
withContentTypeRules({ runUpdateCmd: false }, this.config)
|
|
1825
|
+
);
|
|
1826
|
+
assertFileRefactorSyncConverged(syncResult);
|
|
1758
1827
|
},
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
}
|
|
1763
|
-
).warnings,
|
|
1764
|
-
};
|
|
1828
|
+
}),
|
|
1829
|
+
});
|
|
1830
|
+
return apply;
|
|
1765
1831
|
}
|
|
1766
1832
|
|
|
1767
1833
|
async duplicateNote(
|
|
@@ -1835,6 +1901,62 @@ class GnoClientImpl implements GnoClient {
|
|
|
1835
1901
|
return extractSections(document.content);
|
|
1836
1902
|
}
|
|
1837
1903
|
|
|
1904
|
+
async createSectionTarget(
|
|
1905
|
+
ref: string,
|
|
1906
|
+
selector: SectionTargetCreateSelector
|
|
1907
|
+
): Promise<SectionTargetCreateResult> {
|
|
1908
|
+
this.assertOpen();
|
|
1909
|
+
const parsed = parseSectionTargetCreateSelector(selector);
|
|
1910
|
+
if (!parsed.ok) {
|
|
1911
|
+
throw sdkError("VALIDATION", parsed.error);
|
|
1912
|
+
}
|
|
1913
|
+
const document = await getDocumentByRef(this.store, this.config, ref, {});
|
|
1914
|
+
// Top-level response uri shares schema maxLength — reject before create.
|
|
1915
|
+
if (!isTransportBoundedCanonicalUri(document.uri)) {
|
|
1916
|
+
throw sdkError("VALIDATION", CANONICAL_URI_EXCEEDS_TRANSPORT_BOUNDS);
|
|
1917
|
+
}
|
|
1918
|
+
// Canonical identity from stored document — never from caller.
|
|
1919
|
+
const target = await createSectionTargetCore({
|
|
1920
|
+
content: document.content,
|
|
1921
|
+
uri: document.uri,
|
|
1922
|
+
...parsed.value,
|
|
1923
|
+
});
|
|
1924
|
+
if (!target) {
|
|
1925
|
+
const sections = extractSections(document.content);
|
|
1926
|
+
const matched =
|
|
1927
|
+
parsed.value.anchor !== undefined
|
|
1928
|
+
? sections.some((section) => section.anchor === parsed.value.anchor)
|
|
1929
|
+
: sections.some((section) => section.line === parsed.value.line);
|
|
1930
|
+
if (!matched) {
|
|
1931
|
+
throw sdkError("NOT_FOUND", "Section not found");
|
|
1932
|
+
}
|
|
1933
|
+
throw sdkError("VALIDATION", "Section target exceeds size bounds");
|
|
1934
|
+
}
|
|
1935
|
+
return projectSectionTargetCreateResult(document.uri, target);
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
async resolveSectionTarget(
|
|
1939
|
+
ref: string,
|
|
1940
|
+
target: SectionTargetV1
|
|
1941
|
+
): Promise<SectionTargetResolveResult> {
|
|
1942
|
+
this.assertOpen();
|
|
1943
|
+
const parsed = parseSectionTargetV1(target);
|
|
1944
|
+
if (!parsed.ok) {
|
|
1945
|
+
throw sdkError("VALIDATION", parsed.error);
|
|
1946
|
+
}
|
|
1947
|
+
const document = await getDocumentByRef(this.store, this.config, ref, {});
|
|
1948
|
+
// Top-level uri must fit schema — citation fail-closed does not repair it.
|
|
1949
|
+
if (!isTransportBoundedCanonicalUri(document.uri)) {
|
|
1950
|
+
throw sdkError("VALIDATION", CANONICAL_URI_EXCEEDS_TRANSPORT_BOUNDS);
|
|
1951
|
+
}
|
|
1952
|
+
const resolution = await resolveSectionTargetCore({
|
|
1953
|
+
content: document.content,
|
|
1954
|
+
target: parsed.value,
|
|
1955
|
+
uri: document.uri,
|
|
1956
|
+
});
|
|
1957
|
+
return projectSectionTargetResolveResult(document.uri, resolution);
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1838
1960
|
async close(): Promise<void> {
|
|
1839
1961
|
if (this.closed) {
|
|
1840
1962
|
return;
|
package/src/sdk/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ export type { IndexStatus } from "../store/types";
|
|
|
28
28
|
export { GnoSdkError, sdkError } from "./errors";
|
|
29
29
|
export { createGnoClient } from "./client";
|
|
30
30
|
export type {
|
|
31
|
+
DocumentSection,
|
|
31
32
|
GnoAskOptions,
|
|
32
33
|
GnoCaptureOptions,
|
|
33
34
|
GnoCaptureResult,
|
|
@@ -39,6 +40,9 @@ export type {
|
|
|
39
40
|
GnoClientInitOptions,
|
|
40
41
|
GnoEmbedOptions,
|
|
41
42
|
GnoEmbedResult,
|
|
43
|
+
GnoFileRefactorApplyConfirmation,
|
|
44
|
+
GnoFileRefactorApplyResult,
|
|
45
|
+
GnoFileRefactorPreviewPlan,
|
|
42
46
|
GnoGetOptions,
|
|
43
47
|
GnoGetResult,
|
|
44
48
|
GnoIndexOptions,
|
|
@@ -48,10 +52,14 @@ export type {
|
|
|
48
52
|
GnoListOptions,
|
|
49
53
|
GnoListResult,
|
|
50
54
|
GnoModelOverrides,
|
|
55
|
+
GnoMoveNoteApplyOptions,
|
|
56
|
+
GnoMoveNoteOptions,
|
|
51
57
|
GnoMultiGetDocument,
|
|
52
58
|
GnoMultiGetOptions,
|
|
53
59
|
GnoMultiGetResult,
|
|
54
60
|
GnoQueryOptions,
|
|
61
|
+
GnoRenameNoteApplyOptions,
|
|
62
|
+
GnoRenameNoteOptions,
|
|
55
63
|
GnoProjectHintOptions,
|
|
56
64
|
GnoSearchOptions,
|
|
57
65
|
GnoSkippedDocument,
|
|
@@ -64,6 +72,10 @@ export type {
|
|
|
64
72
|
KnowledgeImpactInput,
|
|
65
73
|
KnowledgeImpactResult,
|
|
66
74
|
ListKnowledgeChangesInput,
|
|
75
|
+
SectionTargetCreateResult,
|
|
76
|
+
SectionTargetCreateSelector,
|
|
77
|
+
SectionTargetResolveResult,
|
|
78
|
+
SectionTargetV1,
|
|
67
79
|
} from "./types";
|
|
68
80
|
export {
|
|
69
81
|
ContextCapsuleContractError,
|
package/src/sdk/types.ts
CHANGED
|
@@ -32,6 +32,10 @@ import type {
|
|
|
32
32
|
EgressAuditShowResult,
|
|
33
33
|
EgressAuditStatusResult,
|
|
34
34
|
} from "../core/egress-audit";
|
|
35
|
+
import type {
|
|
36
|
+
FileRefactorApplyResult,
|
|
37
|
+
FileRefactorPreviewPlan,
|
|
38
|
+
} from "../core/file-refactor-contract";
|
|
35
39
|
import type {
|
|
36
40
|
KnowledgeChangesResult,
|
|
37
41
|
KnowledgeDiffResult,
|
|
@@ -52,7 +56,13 @@ import type {
|
|
|
52
56
|
RetrievalTraceListResult,
|
|
53
57
|
RetrievalTracePurgeResult as RetrievalTraceManagementPurgeResult,
|
|
54
58
|
} from "../core/retrieval-trace-management";
|
|
55
|
-
import type {
|
|
59
|
+
import type {
|
|
60
|
+
DocumentSection,
|
|
61
|
+
SectionTargetCreateResult,
|
|
62
|
+
SectionTargetCreateSelector,
|
|
63
|
+
SectionTargetResolveResult,
|
|
64
|
+
SectionTargetV1,
|
|
65
|
+
} from "../core/sections";
|
|
56
66
|
import type { SyncResult } from "../ingestion";
|
|
57
67
|
import type { DownloadPolicy } from "../llm/policy";
|
|
58
68
|
import type {
|
|
@@ -67,10 +77,15 @@ import type { IndexStatus } from "../store/types";
|
|
|
67
77
|
export type {
|
|
68
78
|
AskResult,
|
|
69
79
|
Config,
|
|
80
|
+
DocumentSection,
|
|
70
81
|
DownloadPolicy,
|
|
71
82
|
IndexStatus,
|
|
72
83
|
SearchOptions,
|
|
73
84
|
SearchResults,
|
|
85
|
+
SectionTargetCreateResult,
|
|
86
|
+
SectionTargetCreateSelector,
|
|
87
|
+
SectionTargetResolveResult,
|
|
88
|
+
SectionTargetV1,
|
|
74
89
|
SyncResult,
|
|
75
90
|
};
|
|
76
91
|
export type { AskOptions, HybridSearchOptions } from "../pipeline/types";
|
|
@@ -251,6 +266,22 @@ export interface GnoMoveNoteOptions {
|
|
|
251
266
|
name?: string;
|
|
252
267
|
}
|
|
253
268
|
|
|
269
|
+
/** Canonical apply confirmation — preview first, then pass exact digest. */
|
|
270
|
+
export interface GnoFileRefactorApplyConfirmation {
|
|
271
|
+
schemaVersion: "1.0";
|
|
272
|
+
planDigest: string;
|
|
273
|
+
confirmation: "apply";
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface GnoRenameNoteApplyOptions
|
|
277
|
+
extends GnoRenameNoteOptions, GnoFileRefactorApplyConfirmation {}
|
|
278
|
+
|
|
279
|
+
export interface GnoMoveNoteApplyOptions
|
|
280
|
+
extends GnoMoveNoteOptions, GnoFileRefactorApplyConfirmation {}
|
|
281
|
+
|
|
282
|
+
export type GnoFileRefactorPreviewPlan = FileRefactorPreviewPlan;
|
|
283
|
+
export type GnoFileRefactorApplyResult = FileRefactorApplyResult;
|
|
284
|
+
|
|
254
285
|
export interface GnoDuplicateNoteOptions {
|
|
255
286
|
ref: string;
|
|
256
287
|
folderPath?: string;
|
|
@@ -339,11 +370,38 @@ export interface GnoClient {
|
|
|
339
370
|
capture(options: GnoCaptureOptions): Promise<GnoCaptureResult>;
|
|
340
371
|
createNote(options: GnoCreateNoteOptions): Promise<GnoCreateNoteResult>;
|
|
341
372
|
createFolder(options: GnoCreateFolderOptions): Promise<GnoCreateFolderResult>;
|
|
342
|
-
|
|
343
|
-
|
|
373
|
+
previewRenameNote(
|
|
374
|
+
options: GnoRenameNoteOptions
|
|
375
|
+
): Promise<GnoFileRefactorPreviewPlan>;
|
|
376
|
+
previewMoveNote(
|
|
377
|
+
options: GnoMoveNoteOptions
|
|
378
|
+
): Promise<GnoFileRefactorPreviewPlan>;
|
|
379
|
+
renameNote(
|
|
380
|
+
options: GnoRenameNoteApplyOptions
|
|
381
|
+
): Promise<GnoFileRefactorApplyResult>;
|
|
382
|
+
moveNote(
|
|
383
|
+
options: GnoMoveNoteApplyOptions
|
|
384
|
+
): Promise<GnoFileRefactorApplyResult>;
|
|
344
385
|
duplicateNote(
|
|
345
386
|
options: GnoDuplicateNoteOptions
|
|
346
387
|
): Promise<GnoRefactorNoteResult>;
|
|
347
388
|
getSections(ref: string): Promise<DocumentSection[]>;
|
|
389
|
+
/**
|
|
390
|
+
* Create a durable SectionTargetV1 for a heading in a stored document.
|
|
391
|
+
* Provide exactly one of `anchor` or `line`. Canonical URI comes from the
|
|
392
|
+
* resolved stored document, never from the caller.
|
|
393
|
+
*/
|
|
394
|
+
createSectionTarget(
|
|
395
|
+
ref: string,
|
|
396
|
+
selector: SectionTargetCreateSelector
|
|
397
|
+
): Promise<SectionTargetCreateResult>;
|
|
398
|
+
/**
|
|
399
|
+
* Conservatively resolve a SectionTargetV1 against a stored document.
|
|
400
|
+
* Navigable results include citation evidence; ambiguous/stale/missing do not.
|
|
401
|
+
*/
|
|
402
|
+
resolveSectionTarget(
|
|
403
|
+
ref: string,
|
|
404
|
+
target: SectionTargetV1
|
|
405
|
+
): Promise<SectionTargetResolveResult>;
|
|
348
406
|
close(): Promise<void>;
|
|
349
407
|
}
|