datanotes 2.0.0 → 3.0.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 (181) hide show
  1. package/NOTICE +9 -0
  2. package/README.md +207 -28
  3. package/SECURITY.md +92 -45
  4. package/dist/THIRD-PARTY-NOTICES.txt +682 -0
  5. package/dist/api/catalog.d.cts +69 -0
  6. package/dist/api/catalog.d.ts +50 -2
  7. package/dist/api/cli-options.d.cts +39 -0
  8. package/dist/api/cli-options.d.ts +39 -0
  9. package/dist/api/client.d.cts +89 -0
  10. package/dist/api/client.d.ts +19 -30
  11. package/dist/api/docs.d.cts +211 -0
  12. package/dist/api/docs.d.ts +211 -0
  13. package/dist/api/guidance.d.cts +81 -0
  14. package/dist/api/guidance.d.ts +81 -0
  15. package/dist/api/index.cjs +6610 -2247
  16. package/dist/api/index.d.cts +13 -0
  17. package/dist/api/index.d.ts +10 -7
  18. package/dist/api/index.js +6610 -2247
  19. package/dist/api/local.cjs +118 -6
  20. package/dist/api/local.d.cts +95 -0
  21. package/dist/api/local.d.ts +70 -6
  22. package/dist/api/local.js +104 -6
  23. package/dist/api/mcp.cjs +17384 -0
  24. package/dist/api/mcp.d.cts +108 -0
  25. package/dist/api/mcp.d.ts +108 -0
  26. package/dist/api/mcp.js +17334 -0
  27. package/dist/api/otlp.d.cts +65 -0
  28. package/dist/api/redact.d.cts +17 -0
  29. package/dist/api/redact.d.ts +17 -0
  30. package/dist/api/requests.d.cts +26 -0
  31. package/dist/api/requests.d.ts +14 -16
  32. package/dist/api/results.d.cts +16 -0
  33. package/dist/api/results.d.ts +2 -1
  34. package/dist/api/tokens.d.cts +7 -0
  35. package/dist/datanotes.cjs +62911 -28409
  36. package/dist/docs/administration/configuration.md +59 -0
  37. package/dist/docs/administration/docker.md +80 -0
  38. package/dist/docs/administration/git-sync.md +71 -0
  39. package/dist/docs/administration/limits.md +69 -0
  40. package/dist/docs/administration/run-the-service.md +219 -0
  41. package/dist/docs/administration/status.md +61 -0
  42. package/dist/docs/administration/use-with-obsidian.md +75 -0
  43. package/dist/docs/api/operations/add_column.md +49 -0
  44. package/dist/docs/api/operations/add_constraint.md +55 -0
  45. package/dist/docs/api/operations/adopt_rows.md +50 -0
  46. package/dist/docs/api/operations/align_relations.md +41 -0
  47. package/dist/docs/api/operations/alter_column.md +46 -0
  48. package/dist/docs/api/operations/alter_table.md +67 -0
  49. package/dist/docs/api/operations/batch.md +48 -0
  50. package/dist/docs/api/operations/changes_stream.md +28 -0
  51. package/dist/docs/api/operations/check_table.md +29 -0
  52. package/dist/docs/api/operations/clone_table.md +48 -0
  53. package/dist/docs/api/operations/comment_on.md +42 -0
  54. package/dist/docs/api/operations/configure_database.md +52 -0
  55. package/dist/docs/api/operations/create_table.md +78 -0
  56. package/dist/docs/api/operations/create_view.md +54 -0
  57. package/dist/docs/api/operations/create_webhook.md +37 -0
  58. package/dist/docs/api/operations/define_base.md +52 -0
  59. package/dist/docs/api/operations/delete_rows.md +43 -0
  60. package/dist/docs/api/operations/delete_webhook.md +31 -0
  61. package/dist/docs/api/operations/describe_database.md +30 -0
  62. package/dist/docs/api/operations/describe_history.md +40 -0
  63. package/dist/docs/api/operations/describe_semantic_index.md +24 -0
  64. package/dist/docs/api/operations/describe_table.md +38 -0
  65. package/dist/docs/api/operations/docs.md +13 -0
  66. package/dist/docs/api/operations/drop_column.md +41 -0
  67. package/dist/docs/api/operations/drop_constraint.md +39 -0
  68. package/dist/docs/api/operations/drop_table.md +43 -0
  69. package/dist/docs/api/operations/drop_view.md +38 -0
  70. package/dist/docs/api/operations/engine_status.md +23 -0
  71. package/dist/docs/api/operations/graph_neighbors.md +32 -0
  72. package/dist/docs/api/operations/graph_path.md +32 -0
  73. package/dist/docs/api/operations/graph_traverse.md +43 -0
  74. package/dist/docs/api/operations/identify_session.md +24 -0
  75. package/dist/docs/api/operations/infer_table.md +43 -0
  76. package/dist/docs/api/operations/insert_row.md +48 -0
  77. package/dist/docs/api/operations/list_changes.md +35 -0
  78. package/dist/docs/api/operations/list_folder.md +28 -0
  79. package/dist/docs/api/operations/list_link_targets.md +44 -0
  80. package/dist/docs/api/operations/list_migrations.md +35 -0
  81. package/dist/docs/api/operations/list_tables.md +32 -0
  82. package/dist/docs/api/operations/list_webhooks.md +23 -0
  83. package/dist/docs/api/operations/manual_index.md +14 -0
  84. package/dist/docs/api/operations/manual_page.md +22 -0
  85. package/dist/docs/api/operations/merge_rows.md +44 -0
  86. package/dist/docs/api/operations/move_rows.md +52 -0
  87. package/dist/docs/api/operations/openapi.md +13 -0
  88. package/dist/docs/api/operations/openapi_post.md +20 -0
  89. package/dist/docs/api/operations/read_note.md +29 -0
  90. package/dist/docs/api/operations/recompute_columns.md +44 -0
  91. package/dist/docs/api/operations/record_tool_call.md +36 -0
  92. package/dist/docs/api/operations/rename_column.md +44 -0
  93. package/dist/docs/api/operations/rename_value.md +45 -0
  94. package/dist/docs/api/operations/restore_database.md +51 -0
  95. package/dist/docs/api/operations/restore_table.md +46 -0
  96. package/dist/docs/api/operations/search_notes.md +28 -0
  97. package/dist/docs/api/operations/select_rows.md +61 -0
  98. package/dist/docs/api/operations/semantic_search.md +34 -0
  99. package/dist/docs/api/operations/semantic_search_docs.md +26 -0
  100. package/dist/docs/api/operations/set_table_bases.md +44 -0
  101. package/dist/docs/api/operations/status.md +13 -0
  102. package/dist/docs/api/operations/stop_engine.md +23 -0
  103. package/dist/docs/api/operations/sync_semantic_index.md +33 -0
  104. package/dist/docs/api/operations/table_changes.md +31 -0
  105. package/dist/docs/api/operations/tags/auxiliary.md +14 -0
  106. package/dist/docs/api/operations/tags/change-feed.md +8 -0
  107. package/dist/docs/api/operations/tags/history.md +17 -0
  108. package/dist/docs/api/operations/tags/queries.md +15 -0
  109. package/dist/docs/api/operations/tags/rows-dml.md +16 -0
  110. package/dist/docs/api/operations/tags/schema-ddl.md +22 -0
  111. package/dist/docs/api/operations/tags/service.md +15 -0
  112. package/dist/docs/api/operations/tags/tokens.md +13 -0
  113. package/dist/docs/api/operations/tokens_create.md +34 -0
  114. package/dist/docs/api/operations/tokens_delete.md +29 -0
  115. package/dist/docs/api/operations/tokens_list.md +21 -0
  116. package/dist/docs/api/operations/tokens_me.md +20 -0
  117. package/dist/docs/api/operations/tokens_rotate.md +29 -0
  118. package/dist/docs/api/operations/tokens_update.md +34 -0
  119. package/dist/docs/api/operations/undo_migration.md +46 -0
  120. package/dist/docs/api/operations/update_row.md +60 -0
  121. package/dist/docs/api/operations/update_rows.md +46 -0
  122. package/dist/docs/api/operations/vacuum_table.md +37 -0
  123. package/dist/docs/api.md +135 -0
  124. package/dist/docs/develop/build-an-app.md +320 -0
  125. package/dist/docs/develop/build-on-datanotes.md +138 -0
  126. package/dist/docs/develop/change-feed-and-webhooks.md +70 -0
  127. package/dist/docs/develop/client.md +116 -0
  128. package/dist/docs/develop/concurrency.md +153 -0
  129. package/dist/docs/develop/http-api.md +79 -0
  130. package/dist/docs/develop/telemetry.md +86 -0
  131. package/dist/docs/guides/agents/docs-offline.md +99 -0
  132. package/dist/docs/guides/agents/how-agents-use-datanotes.md +124 -0
  133. package/dist/docs/guides/agents/prompts.md +495 -0
  134. package/dist/docs/guides/agents/reading-errors.md +112 -0
  135. package/dist/docs/guides/data-quality/check-constraints.md +379 -0
  136. package/dist/docs/guides/data-quality/check-table.md +63 -0
  137. package/dist/docs/guides/data-quality/hand-edits.md +507 -0
  138. package/dist/docs/guides/data-quality/sync-between-devices.md +51 -0
  139. package/dist/docs/guides/data-quality/validation.md +90 -0
  140. package/dist/docs/guides/database-objects/bases.md +480 -0
  141. package/dist/docs/guides/database-objects/catalogs-and-schemas.md +897 -0
  142. package/dist/docs/guides/database-objects/columns.md +1332 -0
  143. package/dist/docs/guides/database-objects/relations.md +1454 -0
  144. package/dist/docs/guides/database-objects/tables.md +1404 -0
  145. package/dist/docs/guides/database-objects/views.md +1003 -0
  146. package/dist/docs/guides/history/back-up.md +195 -0
  147. package/dist/docs/guides/history/change-data-feed.md +247 -0
  148. package/dist/docs/guides/history/journal-and-undo.md +262 -0
  149. package/dist/docs/guides/history/restore.md +341 -0
  150. package/dist/docs/guides/history/table-history.md +657 -0
  151. package/dist/docs/guides/history/vacuum.md +35 -0
  152. package/dist/docs/guides/read-and-write/automatic-links.md +768 -0
  153. package/dist/docs/guides/read-and-write/batch.md +139 -0
  154. package/dist/docs/guides/read-and-write/import-notes.md +896 -0
  155. package/dist/docs/guides/read-and-write/joins-and-aggregates.md +251 -0
  156. package/dist/docs/guides/read-and-write/read-and-filter.md +536 -0
  157. package/dist/docs/guides/read-and-write/write-rows.md +573 -0
  158. package/dist/docs/guides/search/link-graph.md +146 -0
  159. package/dist/docs/guides/search/semantic.md +133 -0
  160. package/dist/docs/guides/search/text.md +142 -0
  161. package/dist/docs/guides/security/security-model.md +110 -0
  162. package/dist/docs/guides/security/tokens.md +60 -0
  163. package/dist/docs/guides/security/who-did-what.md +42 -0
  164. package/dist/docs/index.md +113 -0
  165. package/dist/docs/llms.txt +33 -0
  166. package/dist/docs/reference/cli.md +136 -0
  167. package/dist/docs/reference/compatibility.md +63 -0
  168. package/dist/docs/reference/errors.md +72 -0
  169. package/dist/docs/reference/glossary.md +161 -0
  170. package/dist/docs/reference/operations/auxiliary.md +116 -0
  171. package/dist/docs/reference/operations/history.md +168 -0
  172. package/dist/docs/reference/operations/queries.md +169 -0
  173. package/dist/docs/reference/operations/rows.md +185 -0
  174. package/dist/docs/reference/operations/schema.md +316 -0
  175. package/dist/docs/reference/operations.md +96 -0
  176. package/dist/docs/reference/settings.md +31 -0
  177. package/dist/docs/release-notes.md +67 -0
  178. package/dist/docs/start/connect-agents.md +204 -0
  179. package/dist/docs/start/how-it-works.md +317 -0
  180. package/dist/docs/start/quick-start.md +126 -0
  181. package/package.json +59 -14
@@ -0,0 +1,768 @@
1
+ # Automatic links
2
+
3
+ > The text you write links the notes it mentions by name. See what the engine links, how it asks about a doubtful name, and how to turn it off.
4
+
5
+ When you or an agent write a note’s text, the engine links the notes it mentions by name. A review that says Cary Grant links the note `Cary Grant`, even when the agent wrote plain text.
6
+
7
+ The engine links what it’s sure of and asks about the rest. The write’s answer lists the links in `links_added`. It lists the doubtful mentions in `ambiguous_mentions`, each with the notes it may name.
8
+
9
+ ## What the engine links
10
+
11
+ The engine knows every note by its file name and its `aliases` property, rows and plain notes alike. It looks for these names in the text you write:
12
+
13
+ * **`insert_row`**: `body`
14
+ * **`update_row`**: `body`, `body_sections`, `body_prepend` and `body_append`, and only the text you pass
15
+ * **`update_rows`**: `body`
16
+ * **`batch`**: the same operations inside it
17
+
18
+ A mention becomes a link when all of these hold:
19
+
20
+ * **Whole words on one line**: case doesn’t matter for a name of two words or more, and the link keeps your spelling, as in `[[Cary Grant|cary grant]]`.
21
+ * **A capital for one word**: a one-word name links only when you write it with a capital, such as `House` for the note `House` or `house`.
22
+ * **Inside a sentence**: a one-word name at the start of a sentence, a line, a list item or a label isn’t linked. There every word has a capital, so the capital says nothing.
23
+ * **Standing alone**: a name glued to a path, a domain, an address or a snake_case word is part of it, as in `Documents/House/bill.pdf`, `greenmart.com` or `House_new`.
24
+ * **The first mention**: the note gets one link per body, and none when the body links it already.
25
+ * **Another note**: the engine never links the note you write.
26
+ * **A link target**: a row in a table’s archive folder is never one. Neither is a row of a table that isn’t a target, as the next section explains.
27
+ * **The longest name**: `Nora Wells` links the note `Nora Wells`, not the note `Nora`.
28
+
29
+ The engine leaves these parts of the text alone:
30
+
31
+ * **The front matter**, code blocks and inline code
32
+ * **Links**, web addresses, email addresses, tags, HyperText Markup Language (HTML), comments and math
33
+ * **Headings**: a heading’s text is the anchor that `body_sections` and `[[note#heading]]` links look for
34
+ * **Dataview inline fields**: a `key:: value` line, `[key:: value]` and `(key:: value)`
35
+ * **Templater blocks**: `<% ... %>`
36
+
37
+ It also skips names that would link ordinary words:
38
+
39
+ * **Short names**: fewer than three characters, such as `Al`
40
+ * **Numbers, dates and ids**: names without a letter, or named after a date, such as `2026-09-27`
41
+ * **Common words**: names such as `The`, `Index` or `Welcome`
42
+ * **Lowercase words**: a one-word mention in lowercase, such as `will` for the note `Will`
43
+
44
+ In a Markdown table, a link with an alias escapes its bar, as in `[[Cary Grant\|cary grant]]`. The engine treats a line as a table row when it has a bar outside links and code.
45
+
46
+ Each link has the form new links take in your vault, as seen from where the note ends up. A write that renames the note links from its new path. `links_added` lists each link. The links are part of the write. `dry_run` shows them before you write, and `undo_migration` takes them back.
47
+
48
+ ## Which notes a link may point to
49
+
50
+ Plain notes are always link targets. A table decides for its rows with the option `autolink_target`:
51
+
52
+ * **Absent**: the rows are targets, unless the table names them by a date or a time. A table created with `time_column` names its rows that way, as do tables of meals, readings or events.
53
+ * **`true`**: the rows are targets, whatever their file names.
54
+ * **`false`**: the rows are never targets. Set it on a table of tasks, so an old task `Call Oscar` never takes the words `call Oscar` from the person `Oscar`.
55
+
56
+ Pass it to `create_table` or `alter_table`. `alter_table` with `"default"` goes back to the default.
57
+
58
+ ## Writes from sync programs
59
+
60
+ A sync program writes text it copied from elsewhere, such as tasks, calendar events or receipts. That text should stay as it came. Give the program’s token `"autolink": false`, and its writes link nothing unless a write asks with `autolink: true`. [Tokens and permissions](https://datanotes.dev/guides/security/tokens/#turn-automatic-links-off-for-a-sync-program) shows how.
61
+
62
+ ## When the engine asks
63
+
64
+ The engine never guesses. It leaves a mention as text and lists it in `ambiguous_mentions` for one of these reasons:
65
+
66
+ * **`same_name`**: several notes have the name.
67
+ * **`adjacent`**: names of two notes stand side by side and may form one name. With the notes `Nora` and `Wells`, the text `Nora Wells` may name neither of them.
68
+ * **`overlap`**: names of two notes overlap, such as `New York` and `York City` in `New York City`.
69
+ * **`part_of_name`**: a capitalized word next to the name suggests a longer name, such as `Philadelphia` in `The Philadelphia Story`.
70
+ * **`sentence_start`**: a one-word name starts a sentence, a line, a list item or a label, such as `House` in `House: clean the bathroom`.
71
+
72
+ Each entry gives the mention as `text` and the notes it may name as `candidates`. It adds the line around it as `context`, and a `hint`. The other mentions of that name in the same text stay as text too. A `sentence_start` mention is the exception: a later mention of the name inside a sentence is linked. To resolve one:
73
+
74
+ 1. Read the candidates with `read_note`.
75
+ 2. Decide from the text which note the mention names, if any.
76
+ 3. Write the link with `update_row` and `autolink: false`, or leave the text as it is.
77
+
78
+ ## Link the notes a text mentions
79
+
80
+ Write a note’s text as plain prose. The engine links each note the text mentions by name, at its first mention. `links_added` lists the links. This review of Charade names two actors, each a row, and the director, a plain note.
81
+
82
+ **`insert_row`**
83
+
84
+ ```json
85
+ {
86
+ "table": "film",
87
+ "values": { "title": "Charade", "year": 1963 },
88
+ "body": "Cary Grant and Audrey Hepburn in Paris, directed by Stanley Donen.\n\nCary Grant has never been more charming.\n"
89
+ }
90
+ ```
91
+
92
+ Answer:
93
+
94
+ ```json
95
+ {
96
+ "ok": true,
97
+ "op": "insert_row",
98
+ "files_created": 1,
99
+ "planned_creates": ["datanotes/main/public/film/Charade.md"],
100
+ "commits": [{ "table": "main.public.film", "version": 2, "operation": "WRITE" }],
101
+ "migration_id": "20261012T071956-insert_row-insert-into-film-2",
102
+ "links_added": [
103
+ {
104
+ "path": "datanotes/main/public/film/Charade.md",
105
+ "text": "Cary Grant",
106
+ "target": "datanotes/main/public/actor/Cary Grant.md",
107
+ "link": "[[Cary Grant]]"
108
+ },
109
+ {
110
+ "path": "datanotes/main/public/film/Charade.md",
111
+ "text": "Audrey Hepburn",
112
+ "target": "datanotes/main/public/actor/Audrey Hepburn.md",
113
+ "link": "[[Audrey Hepburn]]"
114
+ },
115
+ {
116
+ "path": "datanotes/main/public/film/Charade.md",
117
+ "text": "Stanley Donen",
118
+ "target": "People/Stanley Donen.md",
119
+ "link": "[[Stanley Donen]]"
120
+ }
121
+ ]
122
+ }
123
+ ```
124
+
125
+ `datanotes/main/public/film/Charade.md` now reads:
126
+
127
+ ```markdown
128
+ ---
129
+ table: main.public.film
130
+ id: 01a12efb-7eff-795a-b759-91ed39941b17
131
+ title: Charade
132
+ year: 1963
133
+ ---
134
+ [[Cary Grant]] and [[Audrey Hepburn]] in Paris, directed by [[Stanley Donen]].
135
+
136
+
137
+ Cary Grant has never been more charming.
138
+ ```
139
+
140
+ The second mention of Cary Grant stays as text: one link per note is enough. Paris has no note, so it stays as text too.
141
+
142
+ ## Link only the text you add
143
+
144
+ `update_row` links the text it writes, and leaves the rest of the note alone. A note the body links already doesn’t get a second link.
145
+
146
+ **`update_row`**
147
+
148
+ ```json
149
+ {
150
+ "table": "film",
151
+ "path": "datanotes/main/public/film/Charade.md",
152
+ "body_append": "Audrey Hepburn wears Givenchy. Watch it with Notorious, the other Cary Grant thriller.\n"
153
+ }
154
+ ```
155
+
156
+ Answer:
157
+
158
+ ```json
159
+ {
160
+ "ok": true,
161
+ "op": "update_row",
162
+ "notes_changed": 1,
163
+ "planned_edits": [
164
+ {
165
+ "path": "datanotes/main/public/film/Charade.md",
166
+ "set": {},
167
+ "remove": [],
168
+ "body": true
169
+ }
170
+ ],
171
+ "commits": [{ "table": "main.public.film", "version": 3, "operation": "UPDATE" }],
172
+ "migration_id": "20261012T071956-update_row-update-film",
173
+ "links_added": [
174
+ {
175
+ "path": "datanotes/main/public/film/Charade.md",
176
+ "text": "Notorious",
177
+ "target": "datanotes/main/public/film/Notorious.md",
178
+ "link": "[[Notorious]]"
179
+ }
180
+ ]
181
+ }
182
+ ```
183
+
184
+ `datanotes/main/public/film/Charade.md` now reads:
185
+
186
+ ```markdown
187
+ ---
188
+ table: main.public.film
189
+ id: 01a12efb-7eff-795a-b759-91ed39941b17
190
+ title: Charade
191
+ year: 1963
192
+ ---
193
+ [[Cary Grant]] and [[Audrey Hepburn]] in Paris, directed by [[Stanley Donen]].
194
+
195
+
196
+ Cary Grant has never been more charming.
197
+
198
+
199
+ Audrey Hepburn wears Givenchy. Watch it with [[Notorious]], the other Cary Grant thriller.
200
+ ```
201
+
202
+ ## Resolve a doubtful mention
203
+
204
+ When the engine can’t tell which note a name means, it leaves the text alone and asks. This review of Notorious names Ingrid Bergman. The vault has your friend `Ingrid` and the director `Bergman`, but no note for the actress. The engine links neither.
205
+
206
+ **`update_row`**
207
+
208
+ ```json
209
+ {
210
+ "table": "film",
211
+ "path": "datanotes/main/public/film/Notorious.md",
212
+ "body": "Ingrid Bergman and Cary Grant, directed by Alfred Hitchcock.\n"
213
+ }
214
+ ```
215
+
216
+ Answer:
217
+
218
+ ```json
219
+ {
220
+ "ok": true,
221
+ "op": "update_row",
222
+ "notes_changed": 1,
223
+ "planned_edits": [
224
+ {
225
+ "path": "datanotes/main/public/film/Notorious.md",
226
+ "set": {},
227
+ "remove": [],
228
+ "body": true
229
+ }
230
+ ],
231
+ "commits": [{ "table": "main.public.film", "version": 4, "operation": "UPDATE" }],
232
+ "migration_id": "20261012T071956-update_row-update-film-2",
233
+ "links_added": [
234
+ {
235
+ "path": "datanotes/main/public/film/Notorious.md",
236
+ "text": "Cary Grant",
237
+ "target": "datanotes/main/public/actor/Cary Grant.md",
238
+ "link": "[[Cary Grant]]"
239
+ }
240
+ ],
241
+ "ambiguous_mentions": [
242
+ {
243
+ "path": "datanotes/main/public/film/Notorious.md",
244
+ "text": "Ingrid Bergman",
245
+ "reason": "adjacent",
246
+ "candidates": ["Directors/Bergman.md", "Friends/Ingrid.md"],
247
+ "context": "Ingrid Bergman and Cary Grant, directed by Alfred Hitchcock.",
248
+ "hint": "\"Ingrid Bergman\" may name one thing, and each note names a part of it: read the notes and the text around it, then write the link with update_row and autolink: false, or leave the text as it is."
249
+ }
250
+ ]
251
+ }
252
+ ```
253
+
254
+ The agent reads both candidates and the line around the mention. Neither note is the actress, so it adds her as an actor:
255
+
256
+ **`insert_row`**
257
+
258
+ ```json
259
+ { "table": "actor", "values": { "name": "Ingrid Bergman" } }
260
+ ```
261
+
262
+ Now the longest name wins. The same text links the actress, and nobody is asked:
263
+
264
+ **`update_row`**
265
+
266
+ ```json
267
+ {
268
+ "table": "film",
269
+ "path": "datanotes/main/public/film/Notorious.md",
270
+ "body": "Ingrid Bergman and Cary Grant, directed by Alfred Hitchcock.\n"
271
+ }
272
+ ```
273
+
274
+ Answer:
275
+
276
+ ```json
277
+ {
278
+ "ok": true,
279
+ "op": "update_row",
280
+ "notes_changed": 1,
281
+ "planned_edits": [
282
+ {
283
+ "path": "datanotes/main/public/film/Notorious.md",
284
+ "set": {},
285
+ "remove": [],
286
+ "body": true
287
+ }
288
+ ],
289
+ "commits": [{ "table": "main.public.film", "version": 5, "operation": "UPDATE" }],
290
+ "migration_id": "20261012T071956-update_row-update-film-3",
291
+ "links_added": [
292
+ {
293
+ "path": "datanotes/main/public/film/Notorious.md",
294
+ "text": "Ingrid Bergman",
295
+ "target": "datanotes/main/public/actor/Ingrid Bergman.md",
296
+ "link": "[[Ingrid Bergman]]"
297
+ },
298
+ {
299
+ "path": "datanotes/main/public/film/Notorious.md",
300
+ "text": "Cary Grant",
301
+ "target": "datanotes/main/public/actor/Cary Grant.md",
302
+ "link": "[[Cary Grant]]"
303
+ }
304
+ ]
305
+ }
306
+ ```
307
+
308
+ `datanotes/main/public/film/Notorious.md` now reads:
309
+
310
+ ```markdown
311
+ ---
312
+ table: main.public.film
313
+ id: 01a12efb-7ef7-77d9-9050-281d995d2d49
314
+ title: Notorious
315
+ year: 1946
316
+ ---
317
+ [[Ingrid Bergman]] and [[Cary Grant]], directed by Alfred Hitchcock.
318
+ ```
319
+
320
+ To link a candidate yourself, write the link in the text and pass `autolink: false`. The engine then writes the text as you give it. If no candidate fits and the name deserves no note, leave the text as it is.
321
+
322
+ ## Choose the tables a link may point to
323
+
324
+ A table’s rows are link targets by default. A table whose rows are named by a date or a time is the exception, such as a table of meals or screenings. The table option `autolink_target` decides for one table. These tasks say no, so the task `Call Ingrid` never takes a mention of Ingrid:
325
+
326
+ **`create_table`**
327
+
328
+ ```json
329
+ {
330
+ "name": "task",
331
+ "columns": [
332
+ {
333
+ "name": "title",
334
+ "type": "string",
335
+ "required": true,
336
+ "description": "What to do, in a few words"
337
+ }
338
+ ],
339
+ "filename": "{title}",
340
+ "description": "Things I have to do",
341
+ "autolink_target": false
342
+ }
343
+ ```
344
+
345
+ Answer:
346
+
347
+ ```json
348
+ { "ok": true }
349
+ ```
350
+
351
+ **`insert_row`**
352
+
353
+ ```json
354
+ { "table": "task", "values": { "title": "Call Ingrid" } }
355
+ ```
356
+
357
+ **`insert_row`**
358
+
359
+ ```json
360
+ {
361
+ "table": "film",
362
+ "values": { "title": "Persona", "year": 1966 },
363
+ "body": "After the film, call Ingrid to talk about it.\n"
364
+ }
365
+ ```
366
+
367
+ Answer:
368
+
369
+ ```json
370
+ {
371
+ "ok": true,
372
+ "op": "insert_row",
373
+ "files_created": 1,
374
+ "planned_creates": ["datanotes/main/public/film/Persona.md"],
375
+ "commits": [{ "table": "main.public.film", "version": 6, "operation": "WRITE" }],
376
+ "migration_id": "20261012T071956-insert_row-insert-into-film-3",
377
+ "links_added": [
378
+ {
379
+ "path": "datanotes/main/public/film/Persona.md",
380
+ "text": "Ingrid",
381
+ "target": "Friends/Ingrid.md",
382
+ "link": "[[Ingrid]]"
383
+ }
384
+ ]
385
+ }
386
+ ```
387
+
388
+ `datanotes/main/public/film/Persona.md` now reads:
389
+
390
+ ```markdown
391
+ ---
392
+ table: main.public.film
393
+ id: 01a12efb-7f3f-7575-a9da-6beb5ecbe530
394
+ title: Persona
395
+ year: 1966
396
+ ---
397
+ After the film, call [[Ingrid]] to talk about it.
398
+ ```
399
+
400
+ Screenings are named by the time they start, so they are no targets. This one has an alias you mention in your notes:
401
+
402
+ **`create_table`**
403
+
404
+ ```json
405
+ {
406
+ "name": "screening",
407
+ "time_column": "starts_at",
408
+ "columns": [
409
+ {
410
+ "name": "starts_at",
411
+ "type": "datetime",
412
+ "required": true,
413
+ "description": "When the screening starts"
414
+ },
415
+ {
416
+ "name": "aliases",
417
+ "type": "list",
418
+ "items": "string",
419
+ "description": "Other names of the screening"
420
+ }
421
+ ],
422
+ "description": "Film club screenings"
423
+ }
424
+ ```
425
+
426
+ **`insert_row`**
427
+
428
+ ```json
429
+ {
430
+ "table": "screening",
431
+ "values": { "starts_at": "2026-10-09T21:00", "aliases": ["Swedish night"] }
432
+ }
433
+ ```
434
+
435
+ `autolink_target: true` makes the screenings link targets:
436
+
437
+ **`alter_table`**
438
+
439
+ ```json
440
+ { "table": "screening", "autolink_target": true }
441
+ ```
442
+
443
+ Answer:
444
+
445
+ ```json
446
+ { "ok": true }
447
+ ```
448
+
449
+ **`update_row`**
450
+
451
+ ```json
452
+ {
453
+ "table": "film",
454
+ "path": "datanotes/main/public/film/Persona.md",
455
+ "body_append": "We watched it at Swedish night.\n"
456
+ }
457
+ ```
458
+
459
+ Answer:
460
+
461
+ ```json
462
+ {
463
+ "ok": true,
464
+ "op": "update_row",
465
+ "notes_changed": 1,
466
+ "planned_edits": [
467
+ {
468
+ "path": "datanotes/main/public/film/Persona.md",
469
+ "set": {},
470
+ "remove": [],
471
+ "body": true
472
+ }
473
+ ],
474
+ "commits": [{ "table": "main.public.film", "version": 7, "operation": "UPDATE" }],
475
+ "migration_id": "20261012T071956-update_row-update-film-4",
476
+ "links_added": [
477
+ {
478
+ "path": "datanotes/main/public/film/Persona.md",
479
+ "text": "Swedish night",
480
+ "target": "datanotes/main/public/screening/2026-10-09T2100.md",
481
+ "link": "[[2026-10-09T2100|Swedish night]]"
482
+ }
483
+ ]
484
+ }
485
+ ```
486
+
487
+ `datanotes/main/public/film/Persona.md` now reads:
488
+
489
+ ```markdown
490
+ ---
491
+ table: main.public.film
492
+ id: 01a12efb-7f3f-7575-a9da-6beb5ecbe530
493
+ title: Persona
494
+ year: 1966
495
+ ---
496
+ After the film, call [[Ingrid]] to talk about it.
497
+
498
+
499
+ We watched it at [[2026-10-09T2100|Swedish night]].
500
+ ```
501
+
502
+ `metastore.yaml` keeps the option in the table’s `options`:
503
+
504
+ `datanotes/metastore.yaml` now reads:
505
+
506
+ ```yaml
507
+ # Metastore (Datanotes): catalogs, schemas, tables, columns, views.
508
+ id: 01a12efb-7ed1-752d-9a1f-21e06985a6cb
509
+ config:
510
+ history: true
511
+
512
+
513
+ catalogs:
514
+ main:
515
+ schemas:
516
+ public:
517
+ tables:
518
+ actor:
519
+ description: Actors of the classic films I watch
520
+ options:
521
+ filename: "{name}"
522
+ archive: _archive
523
+ columns:
524
+ - name: id
525
+ type: string
526
+ required: true
527
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
528
+ unique: true
529
+ identity: uuid
530
+ dense: true
531
+ - name: name
532
+ type: string
533
+ required: true
534
+ description: The actor's name, as in the credits
535
+ film:
536
+ description: Classic films I watched, with my reviews
537
+ options:
538
+ filename: "{title}"
539
+ archive: _archive
540
+ columns:
541
+ - name: id
542
+ type: string
543
+ required: true
544
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
545
+ unique: true
546
+ identity: uuid
547
+ dense: true
548
+ - name: title
549
+ type: string
550
+ required: true
551
+ description: The film's title, as on its poster
552
+ - name: year
553
+ type: integer
554
+ description: Year the film first came out
555
+ task:
556
+ description: Things I have to do
557
+ options:
558
+ filename: "{title}"
559
+ archive: _archive
560
+ autolink_target: false
561
+ columns:
562
+ - name: id
563
+ type: string
564
+ required: true
565
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
566
+ unique: true
567
+ identity: uuid
568
+ dense: true
569
+ - name: title
570
+ type: string
571
+ required: true
572
+ description: What to do, in a few words
573
+ screening:
574
+ description: Film club screenings
575
+ options:
576
+ filename: "{starts_at:YYYY-MM-DD[T]HHmm}"
577
+ archive: _archive
578
+ autolink_target: true
579
+ columns:
580
+ - name: id
581
+ type: string
582
+ unique: true
583
+ identity: uuid
584
+ required: true
585
+ dense: true
586
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
587
+ - name: starts_at
588
+ type: datetime
589
+ required: true
590
+ description: When the screening starts
591
+ - name: aliases
592
+ type: list
593
+ items: string
594
+ description: Other names of the screening
595
+ ```
596
+
597
+ Pass `autolink_target: "default"` to `alter_table` to follow the default again. Archived rows are never link targets, whatever the option says.
598
+
599
+ ## Turn automatic links off
600
+
601
+ `autolink: false` writes one text as you give it. To turn the links off for every write, call `configure_database` with `autolink: false`. A write can still ask for them with `autolink: true`.
602
+
603
+ **`insert_row`**
604
+
605
+ ```json
606
+ {
607
+ "table": "film",
608
+ "values": { "title": "His Girl Friday", "year": 1940 },
609
+ "body": "Cary Grant and Rosalind Russell, the fastest talkers in film.\n",
610
+ "autolink": false
611
+ }
612
+ ```
613
+
614
+ Answer:
615
+
616
+ ```json
617
+ {
618
+ "ok": true,
619
+ "op": "insert_row",
620
+ "files_created": 1,
621
+ "planned_creates": ["datanotes/main/public/film/His Girl Friday.md"],
622
+ "commits": [{ "table": "main.public.film", "version": 8, "operation": "WRITE" }],
623
+ "migration_id": "20261012T071956-insert_row-insert-into-film-4"
624
+ }
625
+ ```
626
+
627
+ `datanotes/main/public/film/His Girl Friday.md` now reads:
628
+
629
+ ```markdown
630
+ ---
631
+ table: main.public.film
632
+ id: 01a12efb-7f79-70da-99fb-2387bf605ab3
633
+ title: His Girl Friday
634
+ year: 1940
635
+ ---
636
+ Cary Grant and Rosalind Russell, the fastest talkers in film.
637
+ ```
638
+
639
+ **`configure_database`**
640
+
641
+ ```json
642
+ { "autolink": false }
643
+ ```
644
+
645
+ Answer:
646
+
647
+ ```json
648
+ {
649
+ "default_catalog": "main",
650
+ "default_schema": "public",
651
+ "default_partition": "",
652
+ "default_filename": "YYYY-MM-DD[T]HHmm",
653
+ "archive_folder": "_archive",
654
+ "timezone": "",
655
+ "history": true,
656
+ "autolink": false
657
+ }
658
+ ```
659
+
660
+ `metastore.yaml` keeps the setting under `config:`:
661
+
662
+ `datanotes/metastore.yaml` now reads:
663
+
664
+ ```yaml
665
+ # Metastore (Datanotes): catalogs, schemas, tables, columns, views.
666
+ id: 01a12efb-7ed1-752d-9a1f-21e06985a6cb
667
+ config:
668
+ history: true
669
+ autolink: false
670
+
671
+
672
+ catalogs:
673
+ main:
674
+ schemas:
675
+ public:
676
+ tables:
677
+ actor:
678
+ description: Actors of the classic films I watch
679
+ options:
680
+ filename: "{name}"
681
+ archive: _archive
682
+ columns:
683
+ - name: id
684
+ type: string
685
+ required: true
686
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
687
+ unique: true
688
+ identity: uuid
689
+ dense: true
690
+ - name: name
691
+ type: string
692
+ required: true
693
+ description: The actor's name, as in the credits
694
+ film:
695
+ description: Classic films I watched, with my reviews
696
+ options:
697
+ filename: "{title}"
698
+ archive: _archive
699
+ columns:
700
+ - name: id
701
+ type: string
702
+ required: true
703
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
704
+ unique: true
705
+ identity: uuid
706
+ dense: true
707
+ - name: title
708
+ type: string
709
+ required: true
710
+ description: The film's title, as on its poster
711
+ - name: year
712
+ type: integer
713
+ description: Year the film first came out
714
+ task:
715
+ description: Things I have to do
716
+ options:
717
+ filename: "{title}"
718
+ archive: _archive
719
+ autolink_target: false
720
+ columns:
721
+ - name: id
722
+ type: string
723
+ required: true
724
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
725
+ unique: true
726
+ identity: uuid
727
+ dense: true
728
+ - name: title
729
+ type: string
730
+ required: true
731
+ description: What to do, in a few words
732
+ screening:
733
+ description: Film club screenings
734
+ options:
735
+ filename: "{starts_at:YYYY-MM-DD[T]HHmm}"
736
+ archive: _archive
737
+ autolink_target: true
738
+ columns:
739
+ - name: id
740
+ type: string
741
+ unique: true
742
+ identity: uuid
743
+ required: true
744
+ dense: true
745
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
746
+ - name: starts_at
747
+ type: datetime
748
+ required: true
749
+ description: When the screening starts
750
+ - name: aliases
751
+ type: list
752
+ items: string
753
+ description: Other names of the screening
754
+ ```
755
+
756
+ This call turns them on again:
757
+
758
+ **`configure_database`**
759
+
760
+ ```json
761
+ { "autolink": true }
762
+ ```
763
+
764
+ Answer:
765
+
766
+ ```json
767
+ { "autolink": true }
768
+ ```