@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.
Files changed (71) hide show
  1. package/README.md +6 -5
  2. package/assets/skill/SKILL.md +25 -0
  3. package/assets/skill/mcp-reference.md +6 -0
  4. package/browser-extension/artifacts/{gno-browser-clipper-v1.30.7.zip → gno-browser-clipper-v1.32.0.zip} +0 -0
  5. package/browser-extension/artifacts/gno-browser-clipper-v1.32.0.zip.sha256 +1 -0
  6. package/browser-extension/dist/manifest.json +1 -1
  7. package/package.json +1 -1
  8. package/spec/cli.md +19 -0
  9. package/spec/db/schema.sql +55 -0
  10. package/spec/mcp.md +176 -11
  11. package/spec/output-schemas/file-refactor-apply-result.schema.json +305 -0
  12. package/spec/output-schemas/file-refactor-preview.schema.json +393 -0
  13. package/spec/output-schemas/section-target-create-result.schema.json +20 -0
  14. package/spec/output-schemas/section-target-resolve-result.schema.json +194 -0
  15. package/spec/output-schemas/section-target.schema.json +118 -0
  16. package/spec/output-schemas/section.schema.json +113 -0
  17. package/src/core/document-capabilities.ts +13 -0
  18. package/src/core/file-ops.ts +129 -1
  19. package/src/core/file-refactor-adapter.ts +329 -0
  20. package/src/core/file-refactor-apply-edits.ts +61 -0
  21. package/src/core/file-refactor-apply-fs.ts +512 -0
  22. package/src/core/file-refactor-apply-safety.ts +340 -0
  23. package/src/core/file-refactor-apply-validate.ts +401 -0
  24. package/src/core/file-refactor-contract.ts +486 -0
  25. package/src/core/file-refactor-destination.ts +123 -0
  26. package/src/core/file-refactor-from-snapshot.ts +148 -0
  27. package/src/core/file-refactor-journal-port.ts +150 -0
  28. package/src/core/file-refactor-journal.ts +347 -0
  29. package/src/core/file-refactor-paths.ts +60 -0
  30. package/src/core/file-refactor-plan-classify.ts +208 -0
  31. package/src/core/file-refactor-plan-validate.ts +169 -0
  32. package/src/core/file-refactor-planner-types.ts +62 -0
  33. package/src/core/file-refactor-planner.ts +423 -0
  34. package/src/core/file-refactor-resolve.ts +280 -0
  35. package/src/core/file-refactor-service.ts +468 -0
  36. package/src/core/file-refactors.ts +84 -56
  37. package/src/core/link-destination-parse.ts +275 -0
  38. package/src/core/link-inventory-markdown.ts +454 -0
  39. package/src/core/link-inventory-opaque.ts +244 -0
  40. package/src/core/link-inventory-types.ts +47 -0
  41. package/src/core/link-inventory.ts +182 -0
  42. package/src/core/link-relevance.ts +150 -0
  43. package/src/core/section-parse.ts +187 -0
  44. package/src/core/section-target-link.ts +154 -0
  45. package/src/core/section-target-resolve.ts +351 -0
  46. package/src/core/section-target-transport.ts +519 -0
  47. package/src/core/section-target.ts +263 -0
  48. package/src/core/sections.ts +60 -115
  49. package/src/mcp/AGENTS.md +1 -0
  50. package/src/mcp/CLAUDE.md +1 -0
  51. package/src/mcp/http-egress.ts +1 -0
  52. package/src/mcp/tools/index.ts +37 -17
  53. package/src/mcp/tools/sections.ts +512 -0
  54. package/src/mcp/tools/workspace-write.ts +215 -97
  55. package/src/sdk/client.ts +238 -116
  56. package/src/sdk/index.ts +12 -0
  57. package/src/sdk/types.ts +61 -3
  58. package/src/serve/file-refactor-http.ts +239 -0
  59. package/src/serve/public/components/RefactorImpactPreview.tsx +227 -0
  60. package/src/serve/public/globals.built.css +1 -1
  61. package/src/serve/public/lib/section-links.ts +189 -0
  62. package/src/serve/public/pages/DocView.tsx +395 -77
  63. package/src/serve/routes/api.ts +191 -104
  64. package/src/serve/routes/section-targets.ts +221 -0
  65. package/src/serve/server.ts +34 -0
  66. package/src/store/migrations/026-file-refactor-recovery-journal.ts +72 -0
  67. package/src/store/migrations/index.ts +2 -0
  68. package/src/store/sqlite/adapter.ts +452 -0
  69. package/src/store/sqlite/file-refactor-journal-store.ts +275 -0
  70. package/src/store/types.ts +84 -0
  71. package/browser-extension/artifacts/gno-browser-clipper-v1.30.7.zip.sha256 +0 -1
package/README.md CHANGED
@@ -117,7 +117,7 @@ gno daemon --detach # headless indexing + resident MCP gateway
117
117
 
118
118
  <!-- public-truth:current-version -->
119
119
 
120
- > Current release: **v1.30.7** — see [CHANGELOG.md](./CHANGELOG.md)
120
+ > Current release: **v1.32.0** — see [CHANGELOG.md](./CHANGELOG.md)
121
121
 
122
122
  <!-- /public-truth -->
123
123
 
@@ -694,7 +694,7 @@ Open `http://localhost:3000` to:
694
694
  configured MCP retrieval without changing client config. Skill installation
695
695
  is visible, but client runtime execution cannot be proven automatically
696
696
  - **Manage files safely**: Rename, reveal, or move editable files to Trash with explicit index-vs-disk semantics
697
- - **Refactor files safely**: Move, duplicate, and organize editable notes with reference warnings
697
+ - **Refactor files safely**: Preview and atomically rename or move editable notes while GNO rewrites supported wiki and Markdown references; stale or unsafe plans fail closed
698
698
  - **Switch presets**: Change models live without restart
699
699
  - **Command palette**: Jump, create, refactor, and section-navigate from one keyboard-first surface
700
700
 
@@ -723,7 +723,7 @@ Full-featured markdown editor with:
723
723
 
724
724
  ![GNO Document Viewer](./assets/screenshots/webui-doc-view.jpg)
725
725
 
726
- View documents with full context: outgoing links, backlinks, section outline, and AI-powered related notes sidebar.
726
+ View documents with full context: outgoing links, backlinks, section outline, and AI-powered related notes sidebar. Outline copy-link stays human-readable (`#anchor`); an optional citation link adds a bounded durable selector for conservative recovery after edits.
727
727
 
728
728
  ### Browse Workspace
729
729
 
@@ -863,9 +863,10 @@ curl http://localhost:3000/api/health
863
863
  | `/api/docs` | GET | List documents |
864
864
  | `/api/docs` | POST | Create document |
865
865
  | `/api/docs/:id` | PUT | Update document content |
866
- | `/api/docs/:id/move` | POST | Move editable document |
866
+ | `/api/docs/:id/rename` | POST | Apply confirmed safe rename |
867
+ | `/api/docs/:id/move` | POST | Apply confirmed safe move |
867
868
  | `/api/docs/:id/duplicate` | POST | Duplicate editable document |
868
- | `/api/docs/:id/refactor-plan` | POST | Preview file-op warnings |
869
+ | `/api/docs/:id/refactor-plan` | POST | Preview reference-safe plan |
869
870
  | `/api/docs/:id/deactivate` | POST | Remove from index |
870
871
  | `/api/doc` | GET | Get document content |
871
872
  | `/api/doc/:id/sections` | GET | Get document sections |
@@ -329,6 +329,7 @@ When using GNO through MCP, prefer this retrieval order:
329
329
  5. Use graph/link expansion for relationship context: `gno_graph_query` for typed relationship traversal, `gno_graph_neighbors` for nearby documents, `gno_graph_path` for "how are X and Y connected?", `gno_links`/`gno_backlinks` for one-document link expansion, and `gno_similar` for semantic neighbors. Prefer explicit or typed edges over inferred, ambiguous, or similarity edges when confidence matters.
330
330
  6. Use `gno_query_diagnose` when a known target document should have appeared but did not; it reports BM25/vector/fusion/graph/rerank stage presence and filter state.
331
331
  7. Use `gno_get` with `fromLine`/`lineCount` for targeted reads, or `gno_multi_get` to batch top refs.
332
+ 8. Use `gno_section` only when you need a durable section locator or must re-resolve one after edits. Prefer search → `gno_get` for ordinary retrieval. `action=create` needs `ref` plus exactly one of `anchor`|`line`; `action=resolve` needs `ref` plus `target`. Cite or open content only for `exact`/`recovered` results, then follow the tool's ready-to-use `gno_get` guidance (`fromLine = lineStart`; `lineCount = lineEnd - lineStart + 1`). Never navigate or cite `ambiguous`/`stale`/`missing`.
332
333
 
333
334
  For a caller-owned canonical Capsule that should stay fresh locally:
334
335
 
@@ -370,6 +371,7 @@ Use narrower tools when the request tells you to:
370
371
  - `gno_graph_neighbors`: relationship/corpus-navigation questions around a known document
371
372
  - `gno_graph_path`: "how are X and Y connected?" questions
372
373
  - `gno_query_diagnose`: why a named target did or did not surface for a query
374
+ - `gno_section`: create/resolve a durable section target when citation identity matters after edits; follow navigable citations with `gno_get`. Not the default retrieval path.
373
375
 
374
376
  For ambiguous terms, pass `intent` instead of bloating the query text. For typed retrieval, use `queryModes`: `term` for lexical anchors, `intent` for disambiguation, one `hyde` for a hypothetical answer/document.
375
377
 
@@ -497,6 +499,29 @@ search must include the new note. Browser provenance fields are
497
499
  `extractionHash`, `finalBodyHash`, `clipIdentity`, and `previewDigest`—do not
498
500
  invent `sourceHash`.
499
501
 
502
+ ## Reference-Safe Rename and Move
503
+
504
+ When MCP writes are enabled and the user asks to rename or move an editable
505
+ note, always use the operation-specific two-step tool. Never invent a digest or
506
+ collapse preview and apply into one call.
507
+
508
+ 1. Call `gno_rename_note` or `gno_move_note` with `action: "preview"` and the
509
+ exact source/destination.
510
+ 2. Inspect `canApply`, `safety.blockingReasons`, and `examinedReferences`.
511
+ Stop and report ambiguous, malformed, unsupported, read-only, occupied,
512
+ cross-collection, or truncated plans.
513
+ 3. Only after explicit user approval, call the same tool with `action: "apply"`,
514
+ the preview's exact `schemaVersion` and `planDigest`, `confirmation: "apply"`,
515
+ and `confirm: true`.
516
+ 4. Treat `applied_with_sync_pending` as a committed filesystem refactor whose
517
+ index still needs `gno_sync` or `gno_index`; do not retry the file mutation.
518
+ For `stale_plan`, preview again instead of reusing the old digest.
519
+
520
+ Supported wiki and Markdown destinations are rewritten in the same
521
+ all-or-rollback filesystem transaction as the source move. Duplicate and
522
+ create-folder do not retarget inbound references. Authentication alone never
523
+ enables these MCP writes.
524
+
500
525
  ## Collection-specific embedding models
501
526
 
502
527
  Collections can override the global embedding model with `models.embed`.
@@ -107,6 +107,12 @@ Check `gno_status` first when freshness or
107
107
  embeddings may be stale. Use `gno_query_diagnose` when a known target document
108
108
  should have appeared but did not.
109
109
 
110
+ Use `gno_section` only when durable section identity matters (create/resolve a
111
+ `SectionTargetV1`). Prefer ordinary `gno_query` → `gno_get` retrieval first.
112
+ Exact/recovered results include citation lines and ready-to-use `gno_get`
113
+ guidance (`fromLine = lineStart`; `lineCount = lineEnd - lineStart + 1`). Never
114
+ cite or navigate ambiguous/stale/missing results.
115
+
110
116
  Use graph tools for relationship context: `gno_graph` for corpus report/stats,
111
117
  community summaries,
112
118
  `gno_graph_query` for bounded typed-edge traversal,
@@ -0,0 +1 @@
1
+ cb5c4bba8cf1252da4e4fc89f1dc01a8df306851cccb50f636d89a6ef3133cff gno-browser-clipper-v1.32.0.zip
@@ -21,5 +21,5 @@
21
21
  "content_security_policy": {
22
22
  "extension_pages": "script-src 'self'; object-src 'none'; connect-src http://127.0.0.1:*"
23
23
  },
24
- "version": "1.30.7"
24
+ "version": "1.32.0"
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "1.30.7",
3
+ "version": "1.32.0",
4
4
  "description": "Local semantic search for your documents. Index Markdown, PDF, and Office files with hybrid BM25 + vector search.",
5
5
  "keywords": [
6
6
  "embeddings",
package/spec/cli.md CHANGED
@@ -3448,6 +3448,25 @@ Error codes match exit codes: `VALIDATION` (exit 1), `RUNTIME` (exit 2), `NOT_RU
3448
3448
 
3449
3449
  ---
3450
3450
 
3451
+ ## Workspace file refactors (non-CLI)
3452
+
3453
+ Reference-safe note rename and same-collection move use a transport-neutral
3454
+ preview/apply contract defined in `src/core/file-refactors.ts` and frozen as:
3455
+
3456
+ - `gno://schemas/file-refactor-preview@1.0`
3457
+ - `gno://schemas/file-refactor-apply-result@1.0`
3458
+
3459
+ Surfaces that adapt the contract are REST/Web UI, SDK, and write-gated MCP
3460
+ (`gno_rename_note`, `gno_move_note`). This specification intentionally does
3461
+ **not** add a CLI command family or generic action bus for refactors.
3462
+ Duplicate-note and create-folder keep their existing shipped semantics and do
3463
+ not retarget inbound references.
3464
+
3465
+ The contract separates durable filesystem commit/rollback from post-commit
3466
+ index convergence. A successful filesystem refactor is never rolled back solely
3467
+ because reindexing is temporarily unavailable
3468
+ (`applied_with_sync_pending`).
3469
+
3451
3470
  ## See Also
3452
3471
 
3453
3472
  - [MCP Specification](./mcp.md)
@@ -21,6 +21,7 @@
21
21
  -- retrieval_trace_exports/export_traces - Export manifests and trace joins
22
22
  -- document_changes - Bounded metadata-only document lifecycle journal
23
23
  -- document_change_journal_state - Monotonic cursor/retention boundary
24
+ -- file_refactor_recovery_journal - Content-free rename/move recovery receipts
24
25
 
25
26
  -- ─────────────────────────────────────────────────────────────────────────────
26
27
  -- Schema Metadata
@@ -742,3 +743,57 @@ CREATE TABLE IF NOT EXISTS clipper_capture_idempotency (
742
743
 
743
744
  CREATE INDEX IF NOT EXISTS idx_clipper_idempotency_created
744
745
  ON clipper_capture_idempotency(created_at_ms, grant_id, key_hash);
746
+
747
+ -- ─────────────────────────────────────────────────────────────────────────────
748
+ -- File refactor recovery journal (content-free)
749
+ -- ─────────────────────────────────────────────────────────────────────────────
750
+
751
+ -- Durable receipts for multi-file rename/move apply. Stores IDs, digests,
752
+ -- collection/relpaths, phase/state, timestamps, and fingerprints/status only.
753
+ -- Never stores note bodies or replacement content.
754
+ -- Bounded: create prunes oldest terminal receipts (converged/rolled_back/aborted)
755
+ -- under FILE_REFACTOR_JOURNAL_MAX_RECEIPTS; never prunes recovery_required.
756
+
757
+ CREATE TABLE IF NOT EXISTS file_refactor_recovery_journal (
758
+ journal_id TEXT PRIMARY KEY,
759
+ plan_digest TEXT NOT NULL,
760
+ collection TEXT NOT NULL,
761
+ operation TEXT NOT NULL
762
+ CHECK (operation IN ('rename', 'move')),
763
+ source_rel_path TEXT NOT NULL,
764
+ target_rel_path TEXT NOT NULL,
765
+ phase TEXT NOT NULL
766
+ CHECK (phase IN (
767
+ 'prepared', 'staging', 'committing', 'committed', 'sync_pending',
768
+ 'converged', 'rolling_back', 'rolled_back', 'recovery_required',
769
+ 'aborted'
770
+ )),
771
+ phase_ordinal INTEGER NOT NULL CHECK (phase_ordinal >= 0),
772
+ filesystem_state TEXT NOT NULL
773
+ CHECK (filesystem_state IN (
774
+ 'unchanged', 'committed', 'rolled_back', 'recovery_required'
775
+ )),
776
+ index_state TEXT NOT NULL
777
+ CHECK (index_state IN (
778
+ 'not_attempted', 'pending', 'converged', 'skipped'
779
+ )),
780
+ file_entries_json TEXT NOT NULL
781
+ CHECK (length(CAST(file_entries_json AS BLOB)) <= 65536),
782
+ created_at_ms INTEGER NOT NULL CHECK (created_at_ms >= 0),
783
+ updated_at_ms INTEGER NOT NULL CHECK (updated_at_ms >= 0),
784
+ CHECK (length(CAST(journal_id AS BLOB)) BETWEEN 1 AND 128),
785
+ CHECK (
786
+ length(plan_digest) = 64
787
+ AND plan_digest NOT GLOB '*[^0-9a-f]*'
788
+ ),
789
+ CHECK (length(CAST(collection AS BLOB)) BETWEEN 1 AND 256),
790
+ CHECK (length(CAST(source_rel_path AS BLOB)) BETWEEN 1 AND 4096),
791
+ CHECK (length(CAST(target_rel_path AS BLOB)) BETWEEN 1 AND 4096),
792
+ CHECK (updated_at_ms >= created_at_ms)
793
+ );
794
+
795
+ CREATE INDEX IF NOT EXISTS idx_file_refactor_journal_plan_digest
796
+ ON file_refactor_recovery_journal(plan_digest, updated_at_ms DESC, journal_id DESC);
797
+
798
+ CREATE INDEX IF NOT EXISTS idx_file_refactor_journal_collection
799
+ ON file_refactor_recovery_journal(collection, updated_at_ms DESC);
package/spec/mcp.md CHANGED
@@ -166,6 +166,7 @@ Collection names are case-insensitive on input and normalized to lowercase in re
166
166
  - Use `gno_query_diagnose` when a specific important document is missing from results or when you need per-stage retrieval evidence before changing query strategy.
167
167
  - Use `gno_graph_query` for bounded typed-edge traversal over `doc_edges`; keep `gno_graph_neighbors`/`gno_graph_path` for the legacy graph projection.
168
168
  - After search/query returns a `line`, call `gno_get` with `fromLine` and `lineCount` before fetching whole documents.
169
+ - Use `gno_section` to create or resolve durable section targets; only cite/navigate on exact/recovered citations, then follow with `gno_get` line ranges.
169
170
  - Use `gno_multi_get` to batch the top result refs. Keep `maxBytes` bounded to avoid flooding client context.
170
171
  - Check `gno_status` when results look stale, vector search is unavailable, or embedding backlog may explain missing results.
171
172
 
@@ -900,6 +901,67 @@ limited to 242 UTF-8 bytes so `index-<identity>.sqlite` stays within the portabl
900
901
 
901
902
  ---
902
903
 
904
+ ### gno_section
905
+
906
+ Read-only create/resolve for durable `SectionTargetV1` locators against one
907
+ indexed document. Always registered (independent of `enableWrite`). Does not
908
+ write documents, persist targets, or fork the shared parser/resolver.
909
+
910
+ Uses the active indexed store content and the shared core
911
+ create/resolve/transport projection (same bounds, closed validation, and
912
+ fail-closed citation semantics as REST/SDK). Canonical document URI always
913
+ comes from the stored document — never from the caller.
914
+
915
+ **Annotations (descriptive only):**
916
+ `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`,
917
+ `openWorldHint: false`. Authorization remains server-side; annotations do not
918
+ grant or deny writes. `gno_section` is not in `MCP_WRITE_TOOL_NAMES`.
919
+
920
+ **Input Schema (closed, action-discriminated):**
921
+
922
+ ```json
923
+ {
924
+ "type": "object",
925
+ "additionalProperties": false,
926
+ "required": ["action", "ref"],
927
+ "properties": {
928
+ "action": { "enum": ["create", "resolve"] },
929
+ "ref": { "type": "string", "minLength": 1, "maxLength": 2048 },
930
+ "anchor": { "type": "string", "minLength": 1, "maxLength": 512 },
931
+ "line": { "type": "integer", "minimum": 1 },
932
+ "target": { "$ref": "gno://schemas/section-target@1.0" }
933
+ }
934
+ }
935
+ ```
936
+
937
+ The published MCP discovery schema is one closed object because the SDK cannot
938
+ reliably publish/validate Zod unions for tool schemas. Server-side refinements
939
+ enforce the action branches: create requires exactly one of `anchor` or `line`
940
+ (1-based heading line) and forbids `target`; resolve requires a closed
941
+ `SectionTargetV1` and forbids `anchor`/`line`. Unknown fields, unknown actions,
942
+ inverted offsets, and oversized values fail closed before core resolution or
943
+ document reads.
944
+
945
+ **Output Schema:** `gno://schemas/section@1.0`
946
+
947
+ Action-discriminated structured output wrapping the shared create/resolve
948
+ result semantics:
949
+
950
+ - `action: "create"` → `{ schemaVersion:"1.0", action, uri, target }`
951
+ - `action: "resolve"` + `exact`/`recovered` → includes `citation` with
952
+ canonical `uri`, current `anchor`/`title`, inclusive `lineStart`/`lineEnd`,
953
+ and `sourceFingerprint`
954
+ - `action: "resolve"` + `ambiguous`/`stale`/`missing` → omits `citation`;
955
+ model-visible text states the result is not safe to navigate or cite
956
+
957
+ Model-visible `content[0].text` includes the serialized structured JSON for
958
+ MCP 2025-11-25 hosts that ignore `structuredContent`, plus concise `gno_get`
959
+ `fromLine`/`lineCount` follow-up guidance when a navigable citation is present.
960
+
961
+ Existing `gno_get` input/output and line-range behavior are unchanged.
962
+
963
+ ---
964
+
903
965
  ### gno_multi_get
904
966
 
905
967
  Retrieve multiple documents by pattern or list.
@@ -1736,39 +1798,140 @@ Create a folder inside an existing collection (write-enabled).
1736
1798
 
1737
1799
  Rename an editable note in place (write-enabled).
1738
1800
 
1801
+ Same-collection rename is covered by the transport-neutral reference-safe
1802
+ refactor contract (`src/core/file-refactors.ts`). Preview and apply share one
1803
+ versioned schema pair across MCP, REST/SDK, and UI adapters:
1804
+
1805
+ - Preview plan: `gno://schemas/file-refactor-preview@1.0`
1806
+ - Apply result: `gno://schemas/file-refactor-apply-result@1.0`
1807
+
1808
+ The preview enumerates examined wiki/Markdown references with classifications
1809
+ and stable reason codes, destination-only edit spans, precondition fingerprints,
1810
+ a deterministic `planDigest`, safety summary, and `canApply`. Apply requires the
1811
+ exact `planDigest`, confirmation token `apply`, `confirm: true`, and
1812
+ `schemaVersion: "1.0"`. Apply never silently preview-and-confirms. Terminal
1813
+ statuses are `applied`, `applied_with_sync_pending`, `conflict`, `stale_plan`,
1814
+ `unsupported`, and `failed_rolled_back`.
1815
+
1816
+ Filesystem commit (moved note + accepted reference rewrites) is an atomic
1817
+ all-or-rollback boundary. Index/link convergence runs only after a durable
1818
+ filesystem commit and is **not** the same transaction; reindex failure returns
1819
+ `applied_with_sync_pending` without rolling back committed files.
1820
+
1821
+ MCP annotations remain hints, not authorization. Write gating (`--enable-write`)
1822
+ and destructive confirmation (`confirm: true` + `confirmation: "apply"`) still
1823
+ apply. No generic action-bus tool is introduced.
1824
+
1739
1825
  **Input Schema:**
1740
1826
 
1741
1827
  ```json
1742
1828
  {
1743
1829
  "type": "object",
1744
- "properties": {
1745
- "ref": { "type": "string" },
1746
- "name": { "type": "string" }
1747
- },
1748
- "required": ["ref", "name"]
1830
+ "oneOf": [
1831
+ {
1832
+ "properties": {
1833
+ "action": { "const": "preview" },
1834
+ "ref": { "type": "string" },
1835
+ "name": { "type": "string" }
1836
+ },
1837
+ "required": ["action", "ref", "name"],
1838
+ "additionalProperties": false
1839
+ },
1840
+ {
1841
+ "properties": {
1842
+ "action": { "const": "apply" },
1843
+ "ref": { "type": "string" },
1844
+ "name": { "type": "string" },
1845
+ "schemaVersion": { "const": "1.0" },
1846
+ "planDigest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
1847
+ "confirmation": { "const": "apply" },
1848
+ "confirm": { "const": true }
1849
+ },
1850
+ "required": [
1851
+ "action",
1852
+ "ref",
1853
+ "name",
1854
+ "schemaVersion",
1855
+ "planDigest",
1856
+ "confirmation",
1857
+ "confirm"
1858
+ ],
1859
+ "additionalProperties": false
1860
+ }
1861
+ ]
1749
1862
  }
1750
1863
  ```
1751
1864
 
1865
+ **Output Schema:**
1866
+
1867
+ - `action=preview` → `gno://schemas/file-refactor-preview@1.0` (content-free plan)
1868
+ - `action=apply` → `gno://schemas/file-refactor-apply-result@1.0` (content-free receipt)
1869
+
1870
+ Missing or incorrect apply confirmation fails before mutation.
1871
+
1752
1872
  ---
1753
1873
 
1754
1874
  ### gno_move_note
1755
1875
 
1756
1876
  Move an editable note to another folder in the same collection (write-enabled).
1757
1877
 
1878
+ Cross-collection moves are out of scope and fail closed with
1879
+ `cross_collection_unsupported`. Preview/apply semantics, destination-only edit
1880
+ spans, stale-plan protection, and the filesystem-vs-index mutation boundary match
1881
+ `gno_rename_note` and use the same schemas:
1882
+
1883
+ - Preview plan: `gno://schemas/file-refactor-preview@1.0`
1884
+ - Apply result: `gno://schemas/file-refactor-apply-result@1.0`
1885
+
1758
1886
  **Input Schema:**
1759
1887
 
1760
1888
  ```json
1761
1889
  {
1762
1890
  "type": "object",
1763
- "properties": {
1764
- "ref": { "type": "string" },
1765
- "folderPath": { "type": "string" },
1766
- "name": { "type": "string" }
1767
- },
1768
- "required": ["ref", "folderPath"]
1891
+ "oneOf": [
1892
+ {
1893
+ "properties": {
1894
+ "action": { "const": "preview" },
1895
+ "ref": { "type": "string" },
1896
+ "folderPath": { "type": "string" },
1897
+ "name": { "type": "string" }
1898
+ },
1899
+ "required": ["action", "ref", "folderPath"],
1900
+ "additionalProperties": false
1901
+ },
1902
+ {
1903
+ "properties": {
1904
+ "action": { "const": "apply" },
1905
+ "ref": { "type": "string" },
1906
+ "folderPath": { "type": "string" },
1907
+ "name": { "type": "string" },
1908
+ "schemaVersion": { "const": "1.0" },
1909
+ "planDigest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
1910
+ "confirmation": { "const": "apply" },
1911
+ "confirm": { "const": true }
1912
+ },
1913
+ "required": [
1914
+ "action",
1915
+ "ref",
1916
+ "folderPath",
1917
+ "schemaVersion",
1918
+ "planDigest",
1919
+ "confirmation",
1920
+ "confirm"
1921
+ ],
1922
+ "additionalProperties": false
1923
+ }
1924
+ ]
1769
1925
  }
1770
1926
  ```
1771
1927
 
1928
+ **Output Schema:**
1929
+
1930
+ - `action=preview` → `gno://schemas/file-refactor-preview@1.0` (content-free plan)
1931
+ - `action=apply` → `gno://schemas/file-refactor-apply-result@1.0` (content-free receipt)
1932
+
1933
+ Missing or incorrect apply confirmation fails before mutation.
1934
+
1772
1935
  ---
1773
1936
 
1774
1937
  ### gno_duplicate_note
@@ -2181,6 +2344,8 @@ Output schemas include version in `$id`:
2181
2344
 
2182
2345
  - `gno://schemas/search-result@1.0`
2183
2346
  - `gno://schemas/capture-receipt@1.0`
2347
+ - `gno://schemas/file-refactor-preview@1.0`
2348
+ - `gno://schemas/file-refactor-apply-result@1.0`
2184
2349
 
2185
2350
  Clients should check schema version for compatibility.
2186
2351