datanotes 3.3.1 → 3.4.1

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/SECURITY.md +5 -3
  2. package/dist/api/extensions.cjs +141 -5
  3. package/dist/api/extensions.js +141 -5
  4. package/dist/api/index.cjs +141 -5
  5. package/dist/api/index.js +141 -5
  6. package/dist/api/mcp.cjs +141 -5
  7. package/dist/api/mcp.js +141 -5
  8. package/dist/datanotes.cjs +3646 -2403
  9. package/dist/docs/administration/extensions.md +2 -2
  10. package/dist/docs/api/operations/add_column.md +1 -0
  11. package/dist/docs/api/operations/check_table.md +1 -0
  12. package/dist/docs/api/operations/create_table.md +1 -0
  13. package/dist/docs/api/operations/describe_database.md +2 -0
  14. package/dist/docs/api/operations/describe_history.md +1 -0
  15. package/dist/docs/api/operations/describe_semantic_index.md +1 -0
  16. package/dist/docs/api/operations/describe_table.md +1 -0
  17. package/dist/docs/api/operations/graph_neighbors.md +1 -0
  18. package/dist/docs/api/operations/graph_path.md +1 -0
  19. package/dist/docs/api/operations/graph_traverse.md +1 -0
  20. package/dist/docs/api/operations/identify_session.md +1 -0
  21. package/dist/docs/api/operations/infer_table.md +1 -0
  22. package/dist/docs/api/operations/list_changes.md +1 -0
  23. package/dist/docs/api/operations/list_folder.md +1 -0
  24. package/dist/docs/api/operations/list_link_targets.md +1 -0
  25. package/dist/docs/api/operations/list_migrations.md +1 -0
  26. package/dist/docs/api/operations/list_tables.md +2 -0
  27. package/dist/docs/api/operations/list_webhooks.md +1 -0
  28. package/dist/docs/api/operations/read_note.md +1 -0
  29. package/dist/docs/api/operations/record_tool_call.md +1 -0
  30. package/dist/docs/api/operations/search.md +39 -0
  31. package/dist/docs/api/operations/search_notes.md +1 -0
  32. package/dist/docs/api/operations/select_rows.md +1 -0
  33. package/dist/docs/api/operations/semantic_search.md +1 -0
  34. package/dist/docs/api/operations/table_changes.md +1 -0
  35. package/dist/docs/api/operations/tags/queries.md +1 -0
  36. package/dist/docs/api/operations/tags/tokens.md +1 -1
  37. package/dist/docs/api/operations/tokens_create.md +1 -0
  38. package/dist/docs/api/operations/tokens_update.md +2 -1
  39. package/dist/docs/api.md +5 -4
  40. package/dist/docs/develop/build-an-app.md +2 -1
  41. package/dist/docs/develop/change-feed-and-webhooks.md +1 -1
  42. package/dist/docs/develop/http-api.md +1 -1
  43. package/dist/docs/guides/data-quality/check-constraints.md +10 -10
  44. package/dist/docs/guides/data-quality/hand-edits.md +8 -8
  45. package/dist/docs/guides/database-objects/bases.md +11 -11
  46. package/dist/docs/guides/database-objects/catalogs-and-schemas.md +10 -10
  47. package/dist/docs/guides/database-objects/columns.md +241 -38
  48. package/dist/docs/guides/database-objects/relations.md +28 -28
  49. package/dist/docs/guides/database-objects/tables.md +26 -26
  50. package/dist/docs/guides/database-objects/views.md +19 -19
  51. package/dist/docs/guides/history/change-data-feed.md +34 -34
  52. package/dist/docs/guides/history/journal-and-undo.md +12 -12
  53. package/dist/docs/guides/history/restore.md +20 -20
  54. package/dist/docs/guides/history/table-history.md +31 -31
  55. package/dist/docs/guides/read-and-write/automatic-links.md +15 -15
  56. package/dist/docs/guides/read-and-write/import-notes.md +20 -20
  57. package/dist/docs/guides/read-and-write/write-rows.md +10 -10
  58. package/dist/docs/guides/search/hybrid.md +162 -0
  59. package/dist/docs/guides/search/text.md +1 -1
  60. package/dist/docs/guides/security/security-model.md +5 -3
  61. package/dist/docs/guides/security/tokens.md +134 -8
  62. package/dist/docs/guides/security/who-did-what.md +8 -0
  63. package/dist/docs/reference/cli.md +1 -1
  64. package/dist/docs/reference/glossary.md +1 -1
  65. package/dist/docs/reference/operations/auxiliary.md +2 -2
  66. package/dist/docs/reference/operations/queries.md +16 -0
  67. package/dist/docs/reference/operations/schema.md +2 -2
  68. package/dist/docs/reference/operations.md +2 -1
  69. package/dist/docs/release-notes.md +58 -0
  70. package/dist/docs/start/connect-agents.md +10 -3
  71. package/package.json +1 -1
@@ -284,7 +284,7 @@ var OPERATIONS = [
284
284
  },
285
285
  {
286
286
  "name": "list_tables",
287
- "description": "List every table: `name`, `catalog`, `schema`, `qualified` (`personal.metrics.mood` \u2014 use it\nwherever a table is expected; `metrics.mood` or `mood` also work when unambiguous), `path` and,\nwhen declared, `description`, `aliases` (other words for what it records) and `tags`. Tables are\ndefined in `metastore.yaml` (catalog \u2192 schema \u2192 table): read it freely, but it is read-only for\nagents and changes only through the schema operations (create_table, add_column, \u2026). Returns `{tables, views}`: `views` lists the stored views (same fields, no\npath): select them like tables. `system.information_schema` is read with `select_rows`.\n\nCall this first to find the table for what the user reports (match their words against\nname, description and aliases), and before creating tables or columns so you reuse existing\nones instead of creating duplicates.",
287
+ "description": "List every table: `name`, `catalog`, `schema`, `qualified` (`personal.metrics.mood` \u2014 use it\nwherever a table is expected; `metrics.mood` or `mood` also work when unambiguous), `path` and,\nwhen declared, `description`, `aliases` (other words for what it records) and `tags`. Tables are\ndefined in `metastore.yaml` (catalog \u2192 schema \u2192 table): read it freely, but it is read-only for\nagents and changes only through the schema operations (create_table, add_column, \u2026). Returns `{tables, views}`: `views` lists the stored views (same fields, no\npath): select them like tables. `system.information_schema` is read with `select_rows`.\nA token with `read` patterns sees only the tables and views it may read.\n\nCall this first to find the table for what the user reports (match their words against\nname, description and aliases), and before creating tables or columns so you reuse existing\nones instead of creating duplicates.",
288
288
  "inputSchema": {
289
289
  "additionalProperties": false,
290
290
  "properties": {},
@@ -549,7 +549,7 @@ var OPERATIONS = [
549
549
  },
550
550
  "generated": {
551
551
  "type": "string",
552
- "description": "Expression of a generated column."
552
+ "description": 'Expression of a generated column: a column, `date(col)\xB1N`, a template like `{name} {surname}`, `link(<template>)`, or an aggregate of a json list of objects like `count(feeds, side = "left")` or `sum(feeds.min)`.'
553
553
  },
554
554
  "dense": {
555
555
  "type": "boolean",
@@ -670,7 +670,7 @@ var OPERATIONS = [
670
670
  },
671
671
  {
672
672
  "name": "create_table",
673
- "description": 'Create a table: `name`, in `catalog` and `schema` (default: the database\'s defaults); the definition\ngoes in metastore.yaml, the rows in `<root>/<catalog>/<schema>/<name>/`. Names: lowercase letters,\ndigits, `_` (no dots: pass the catalog and the schema as their own arguments).\n- `description` (required): what a row of the table records. Every column needs its own `description`\n too, what it holds: the table is refused otherwise, with every missing one listed. Descriptions are how\n agents and people understand the schema, so write them for a reader who never saw the notes. The\n engine writes those of `id` and of `identity` "uuid" / "created" columns.\n- `columns`: specs like `{"name": "kind", "type": "enum", "values": ["a","b"], "required": true,\n "description": "What kind of entry the row is"}`.\n Types: string, integer, number, boolean, date, datetime, enum, link, list (+ `items`), json.\n Attributes: required, default (`"{now}"`/`"{today}"`), min, max, step, values, `ordered` (enum in\n order: filters/avg use the position), ref (link target, full `catalog.schema.table` or "self"),\n unique, label, description, aliases, `generated` (e.g. `"date(occurred_at)"`, `"{name} {surname}"`),\n `identity` ("filename" | "created"), `vocabulary` (allowed values = names of another table\'s rows),\n `hierarchy: true` (one parent link to its own table), `acyclic: true` (links to rows of its own table that never loop back, such as tasks blocked by tasks; with `inverse`, the rule holds on both sides), `dense` (written on every row),\n `inverse` on a link column: the column of the `ref` table that links back (`friends` \u2194\n `friends`, `children` \u2194 `parents`, `partner` \u2194 `partner`); writes keep both sides in step.\n- `time_column`: rows named by that date/datetime; otherwise `filename` (e.g. `"{name}"`).\n- The table\'s options, as alter_table names them: `aliases` (how agents find it, with the\n description), `partition`, `exclude`, `archive`, `history` (keep its versions; default: the\n database\'s setting), `autolink_target` (true / false: may automatic links link its rows? default:\n yes, unless its rows are named by a date or a time, as with `time_column`).\n- `row_template`: markdown body of new rows. Shared columns come from bases: `set_table_bases`.\n- `instructions`: how to fill a row, for agents (Markdown); describe_table returns them.\n- `tags`: key/value labels of the table, strings (`{"domain": "health"}`); list_tables and\n describe_table return them, alter_table changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", \u2026}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\nFiltered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.\n\nThe schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).',
673
+ "description": 'Create a table: `name`, in `catalog` and `schema` (default: the database\'s defaults); the definition\ngoes in metastore.yaml, the rows in `<root>/<catalog>/<schema>/<name>/`. Names: lowercase letters,\ndigits, `_` (no dots: pass the catalog and the schema as their own arguments).\n- `description` (required): what a row of the table records. Every column needs its own `description`\n too, what it holds: the table is refused otherwise, with every missing one listed. Descriptions are how\n agents and people understand the schema, so write them for a reader who never saw the notes. The\n engine writes those of `id` and of `identity` "uuid" / "created" columns.\n- `columns`: specs like `{"name": "kind", "type": "enum", "values": ["a","b"], "required": true,\n "description": "What kind of entry the row is"}`.\n Types: string, integer, number, boolean, date, datetime, enum, link, list (+ `items`), json.\n Attributes: required, default (`"{now}"`/`"{today}"`), min, max, step, values, `ordered` (enum in\n order: filters/avg use the position), ref (link target, full `catalog.schema.table` or "self"),\n unique, label, description, aliases, `generated` (e.g. `"date(occurred_at)"`, `"{name} {surname}"`),\n `identity` ("filename" | "created"), `vocabulary` (allowed values = names of another table\'s rows),\n `hierarchy: true` (one parent link to its own table), `acyclic: true` (links to rows of its own table that never loop back, such as tasks blocked by tasks; with `inverse`, the rule holds on both sides), `dense` (written on every row),\n `inverse` on a link column: the column of the `ref` table that links back (`friends` \u2194\n `friends`, `children` \u2194 `parents`, `partner` \u2194 `partner`); writes keep both sides in step.\n- `time_column`: rows named by that date/datetime; otherwise `filename` (e.g. `"{name}"`).\n- The table\'s options, as alter_table names them: `aliases` (how agents find it, with the\n description), `partition`, `exclude`, `archive`, `history` (keep its versions; default: the\n database\'s setting), `autolink_target` (true / false: may automatic links link its rows? default:\n yes, unless its rows are named by a date or a time, as with `time_column`).\n- `row_template`: markdown body of new rows. Shared columns come from bases: `set_table_bases`.\n- `instructions`: how to fill a row, for agents (Markdown); describe_table returns them.\n- `tags`: key/value labels of the table, strings (`{"domain": "health"}`); list_tables and\n describe_table return them, alter_table changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", \u2026}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\nGenerated aggregates of a json column holding a list of objects (integer or number columns; avg: number): `count(feeds)`, `count(feeds.min)` (the items with a min), `sum(feeds.min)`, `avg(\u2026)`, `min(\u2026)`, `max(\u2026)`, with an optional filter on one field: `count(feeds, side = "left")`, `sum(feeds.min, min > 0)` (=, !=, <, <=, >, >=; "text", a number, true or false). Recomputed on every write; no list: count and sum 0, avg/min/max empty; a field that is not a number: empty.\nFiltered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.\n\nThe schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).',
674
674
  "inputSchema": {
675
675
  "additionalProperties": false,
676
676
  "properties": {
@@ -1764,7 +1764,7 @@ var OPERATIONS = [
1764
1764
  },
1765
1765
  {
1766
1766
  "name": "add_column",
1767
- "description": 'Add a typed column. Sparse by default (written only on rows that have a value \u2014 use for\nmetrics, e.g. `{"name": "metric_mood", "type": "integer", "min": 1, "max": 5, "label":\n"Mood", "aliases": ["mood"], "description": "Mood of the day, 1 = bad, 5 = great"}`).\n`description` is required: what the column holds, for the agents and people who read the schema\n(the engine writes it for `identity` "uuid" / "created" columns).\n`dense: true` in the spec adds it to every row with its `default`. Call `describe_table` first: never add\na column whose meaning an existing column (name/label/aliases/description) already covers.\nColumn names are permanent identifiers; only `rename_column` changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", \u2026}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\nFiltered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.\nAcyclic links: `acyclic: true` on a link (or list of links) to the table itself refuses every write that closes a cycle, on either side of an `inverse`; refused while existing rows form one (they are listed).\n\nThe schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).',
1767
+ "description": 'Add a typed column. Sparse by default (written only on rows that have a value \u2014 use for\nmetrics, e.g. `{"name": "metric_mood", "type": "integer", "min": 1, "max": 5, "label":\n"Mood", "aliases": ["mood"], "description": "Mood of the day, 1 = bad, 5 = great"}`).\n`description` is required: what the column holds, for the agents and people who read the schema\n(the engine writes it for `identity` "uuid" / "created" columns).\n`dense: true` in the spec adds it to every row with its `default`. Call `describe_table` first: never add\na column whose meaning an existing column (name/label/aliases/description) already covers.\nColumn names are permanent identifiers; only `rename_column` changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", \u2026}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\nGenerated aggregates of a json column holding a list of objects (integer or number columns; avg: number): `count(feeds)`, `count(feeds.min)` (the items with a min), `sum(feeds.min)`, `avg(\u2026)`, `min(\u2026)`, `max(\u2026)`, with an optional filter on one field: `count(feeds, side = "left")`, `sum(feeds.min, min > 0)` (=, !=, <, <=, >, >=; "text", a number, true or false). Recomputed on every write; no list: count and sum 0, avg/min/max empty; a field that is not a number: empty.\nFiltered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.\nAcyclic links: `acyclic: true` on a link (or list of links) to the table itself refuses every write that closes a cycle, on either side of an `inverse`; refused while existing rows form one (they are listed).\n\nThe schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).',
1768
1768
  "inputSchema": {
1769
1769
  "additionalProperties": false,
1770
1770
  "properties": {
@@ -5163,7 +5163,7 @@ var OPERATIONS = [
5163
5163
  },
5164
5164
  {
5165
5165
  "name": "describe_database",
5166
- "description": "Describe the database: its folder (`root`), `metastore` (`metastore.yaml`: read it freely,\nbut it is read-only for agents and changes only through the schema operations), configuration\n(default catalog and schema, row partition and file-name formats, archive folder, time zone,\nhistory, automatic links),\njournal folder, `bases` (shared column sets and the tables using them), `catalogs` \u2192 `schemas` \u2192 `tables` (with `row_count`, `tags`, and `unreadable_count` when some rows' front matter cannot be read) and `views`;\ncatalogs and schemas show their `comment` (set with `comment_on`). A table or base defined before\ndescriptions were required has `missing_descriptions`: what lacks one, for alter_table / alter_column\n(define_base for a base) to fill, so every table and column says what it holds.",
5166
+ "description": "Describe the database: its folder (`root`), `metastore` (`metastore.yaml`: read it freely,\nbut it is read-only for agents and changes only through the schema operations), configuration\n(default catalog and schema, row partition and file-name formats, archive folder, time zone,\nhistory, automatic links),\njournal folder, `bases` (shared column sets and the tables using them), `catalogs` \u2192 `schemas` \u2192 `tables` (with `row_count`, `tags`, and `unreadable_count` when some rows' front matter cannot be read) and `views`;\ncatalogs and schemas show their `comment` (set with `comment_on`). A table or base defined before\ndescriptions were required has `missing_descriptions`: what lacks one, for alter_table / alter_column\n(define_base for a base) to fill, so every table and column says what it holds.\nA token with `read` patterns sees only the tables, views and bases it may read.",
5167
5167
  "inputSchema": {
5168
5168
  "additionalProperties": false,
5169
5169
  "properties": {},
@@ -11727,6 +11727,141 @@ var OPERATIONS = [
11727
11727
  ]
11728
11728
  }
11729
11729
  },
11730
+ {
11731
+ "name": "search",
11732
+ "description": "Search the notes by their words and, when semantic search is on, by their meaning:\n`{query, results: [{path, table?, score, heading, snippet, matched_by}], meaning}`, one result per\nnote, best first. It always works: with semantic search off it ranks by words alone (BM25:\nrare words count more; a word in the note's name or properties counts more), with it on it fuses\nboth rankings (Reciprocal Rank Fusion), so a note found only by its words or only by its meaning\nis still there. `matched_by` says which (`words`, `meaning`); `meaning` is `on`, `off` or `failed`\n(the embedding provider failed: words only, `meaning_error` says why). Query syntax as search_docs:\n`\"a phrase\"` and `+word` must appear, `-word` must not (both rankings); words in any language,\ncase and accents ignored, no stemming. Filters: `tables` (qualified or short names), `folder`,\n`min_score` (the meaning ranking's cosine floor). `limit`: default 10, max 100. Then read_note /\nselect_rows for the details.",
11733
+ "inputSchema": {
11734
+ "additionalProperties": false,
11735
+ "properties": {
11736
+ "query": {
11737
+ "type": "string"
11738
+ },
11739
+ "limit": {
11740
+ "default": 10,
11741
+ "type": "integer"
11742
+ },
11743
+ "tables": {
11744
+ "anyOf": [
11745
+ {
11746
+ "items": {
11747
+ "type": "string"
11748
+ },
11749
+ "type": "array"
11750
+ },
11751
+ {
11752
+ "type": "null"
11753
+ }
11754
+ ],
11755
+ "default": null
11756
+ },
11757
+ "folder": {
11758
+ "anyOf": [
11759
+ {
11760
+ "type": "string"
11761
+ },
11762
+ {
11763
+ "type": "null"
11764
+ }
11765
+ ],
11766
+ "default": null
11767
+ },
11768
+ "min_score": {
11769
+ "anyOf": [
11770
+ {
11771
+ "type": "number"
11772
+ },
11773
+ {
11774
+ "type": "null"
11775
+ }
11776
+ ],
11777
+ "default": null
11778
+ }
11779
+ },
11780
+ "required": [
11781
+ "query"
11782
+ ],
11783
+ "type": "object"
11784
+ },
11785
+ "annotations": {
11786
+ "title": "Search",
11787
+ "readOnlyHint": true,
11788
+ "destructiveHint": false,
11789
+ "idempotentHint": true,
11790
+ "openWorldHint": false
11791
+ },
11792
+ "responseSchema": {
11793
+ "type": "object",
11794
+ "properties": {
11795
+ "query": {
11796
+ "type": "string"
11797
+ },
11798
+ "results": {
11799
+ "type": "array",
11800
+ "items": {
11801
+ "type": "object",
11802
+ "properties": {
11803
+ "path": {
11804
+ "type": "string"
11805
+ },
11806
+ "table": {
11807
+ "type": "string",
11808
+ "description": "Qualified table of a row note."
11809
+ },
11810
+ "score": {
11811
+ "type": "number",
11812
+ "description": "BM25 when ranked by words alone; the Reciprocal Rank Fusion score when fused."
11813
+ },
11814
+ "heading": {
11815
+ "type": "string",
11816
+ "description": "Heading above the match (empty before the first heading)."
11817
+ },
11818
+ "snippet": {
11819
+ "type": "string",
11820
+ "description": "About 200 characters around the first match, or the best passage by meaning."
11821
+ },
11822
+ "matched_by": {
11823
+ "type": "array",
11824
+ "items": {
11825
+ "type": "string",
11826
+ "enum": [
11827
+ "words",
11828
+ "meaning"
11829
+ ]
11830
+ },
11831
+ "description": "The rankings the note is in."
11832
+ }
11833
+ },
11834
+ "required": [
11835
+ "path",
11836
+ "score",
11837
+ "heading",
11838
+ "snippet",
11839
+ "matched_by"
11840
+ ]
11841
+ },
11842
+ "description": "One result per note, best first."
11843
+ },
11844
+ "meaning": {
11845
+ "type": "string",
11846
+ "enum": [
11847
+ "on",
11848
+ "off",
11849
+ "failed"
11850
+ ],
11851
+ "description": "on: words and meaning fused; off: semantic search is off, words only; failed: the embedding provider failed, words only."
11852
+ },
11853
+ "meaning_error": {
11854
+ "type": "string",
11855
+ "description": "Why the meaning ranking failed (with meaning: failed)."
11856
+ }
11857
+ },
11858
+ "required": [
11859
+ "query",
11860
+ "results",
11861
+ "meaning"
11862
+ ]
11863
+ }
11864
+ },
11730
11865
  {
11731
11866
  "name": "describe_semantic_index",
11732
11867
  "description": "The semantic search index: `enabled`, `provider`, `model`, `files`, `passages`, `pending`,\n`running`, `last_sync`, `last_error`. sync_semantic_index brings it up to date.",
@@ -17852,6 +17987,7 @@ var OPERATION_KIND = {
17852
17987
  list_folder: "queries",
17853
17988
  search_notes: "queries",
17854
17989
  semantic_search: "queries",
17990
+ search: "queries",
17855
17991
  graph_neighbors: "queries",
17856
17992
  graph_traverse: "queries",
17857
17993
  graph_path: "queries",
package/dist/api/index.js CHANGED
@@ -224,7 +224,7 @@ var OPERATIONS = [
224
224
  },
225
225
  {
226
226
  "name": "list_tables",
227
- "description": "List every table: `name`, `catalog`, `schema`, `qualified` (`personal.metrics.mood` \u2014 use it\nwherever a table is expected; `metrics.mood` or `mood` also work when unambiguous), `path` and,\nwhen declared, `description`, `aliases` (other words for what it records) and `tags`. Tables are\ndefined in `metastore.yaml` (catalog \u2192 schema \u2192 table): read it freely, but it is read-only for\nagents and changes only through the schema operations (create_table, add_column, \u2026). Returns `{tables, views}`: `views` lists the stored views (same fields, no\npath): select them like tables. `system.information_schema` is read with `select_rows`.\n\nCall this first to find the table for what the user reports (match their words against\nname, description and aliases), and before creating tables or columns so you reuse existing\nones instead of creating duplicates.",
227
+ "description": "List every table: `name`, `catalog`, `schema`, `qualified` (`personal.metrics.mood` \u2014 use it\nwherever a table is expected; `metrics.mood` or `mood` also work when unambiguous), `path` and,\nwhen declared, `description`, `aliases` (other words for what it records) and `tags`. Tables are\ndefined in `metastore.yaml` (catalog \u2192 schema \u2192 table): read it freely, but it is read-only for\nagents and changes only through the schema operations (create_table, add_column, \u2026). Returns `{tables, views}`: `views` lists the stored views (same fields, no\npath): select them like tables. `system.information_schema` is read with `select_rows`.\nA token with `read` patterns sees only the tables and views it may read.\n\nCall this first to find the table for what the user reports (match their words against\nname, description and aliases), and before creating tables or columns so you reuse existing\nones instead of creating duplicates.",
228
228
  "inputSchema": {
229
229
  "additionalProperties": false,
230
230
  "properties": {},
@@ -489,7 +489,7 @@ var OPERATIONS = [
489
489
  },
490
490
  "generated": {
491
491
  "type": "string",
492
- "description": "Expression of a generated column."
492
+ "description": 'Expression of a generated column: a column, `date(col)\xB1N`, a template like `{name} {surname}`, `link(<template>)`, or an aggregate of a json list of objects like `count(feeds, side = "left")` or `sum(feeds.min)`.'
493
493
  },
494
494
  "dense": {
495
495
  "type": "boolean",
@@ -610,7 +610,7 @@ var OPERATIONS = [
610
610
  },
611
611
  {
612
612
  "name": "create_table",
613
- "description": 'Create a table: `name`, in `catalog` and `schema` (default: the database\'s defaults); the definition\ngoes in metastore.yaml, the rows in `<root>/<catalog>/<schema>/<name>/`. Names: lowercase letters,\ndigits, `_` (no dots: pass the catalog and the schema as their own arguments).\n- `description` (required): what a row of the table records. Every column needs its own `description`\n too, what it holds: the table is refused otherwise, with every missing one listed. Descriptions are how\n agents and people understand the schema, so write them for a reader who never saw the notes. The\n engine writes those of `id` and of `identity` "uuid" / "created" columns.\n- `columns`: specs like `{"name": "kind", "type": "enum", "values": ["a","b"], "required": true,\n "description": "What kind of entry the row is"}`.\n Types: string, integer, number, boolean, date, datetime, enum, link, list (+ `items`), json.\n Attributes: required, default (`"{now}"`/`"{today}"`), min, max, step, values, `ordered` (enum in\n order: filters/avg use the position), ref (link target, full `catalog.schema.table` or "self"),\n unique, label, description, aliases, `generated` (e.g. `"date(occurred_at)"`, `"{name} {surname}"`),\n `identity` ("filename" | "created"), `vocabulary` (allowed values = names of another table\'s rows),\n `hierarchy: true` (one parent link to its own table), `acyclic: true` (links to rows of its own table that never loop back, such as tasks blocked by tasks; with `inverse`, the rule holds on both sides), `dense` (written on every row),\n `inverse` on a link column: the column of the `ref` table that links back (`friends` \u2194\n `friends`, `children` \u2194 `parents`, `partner` \u2194 `partner`); writes keep both sides in step.\n- `time_column`: rows named by that date/datetime; otherwise `filename` (e.g. `"{name}"`).\n- The table\'s options, as alter_table names them: `aliases` (how agents find it, with the\n description), `partition`, `exclude`, `archive`, `history` (keep its versions; default: the\n database\'s setting), `autolink_target` (true / false: may automatic links link its rows? default:\n yes, unless its rows are named by a date or a time, as with `time_column`).\n- `row_template`: markdown body of new rows. Shared columns come from bases: `set_table_bases`.\n- `instructions`: how to fill a row, for agents (Markdown); describe_table returns them.\n- `tags`: key/value labels of the table, strings (`{"domain": "health"}`); list_tables and\n describe_table return them, alter_table changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", \u2026}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\nFiltered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.\n\nThe schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).',
613
+ "description": 'Create a table: `name`, in `catalog` and `schema` (default: the database\'s defaults); the definition\ngoes in metastore.yaml, the rows in `<root>/<catalog>/<schema>/<name>/`. Names: lowercase letters,\ndigits, `_` (no dots: pass the catalog and the schema as their own arguments).\n- `description` (required): what a row of the table records. Every column needs its own `description`\n too, what it holds: the table is refused otherwise, with every missing one listed. Descriptions are how\n agents and people understand the schema, so write them for a reader who never saw the notes. The\n engine writes those of `id` and of `identity` "uuid" / "created" columns.\n- `columns`: specs like `{"name": "kind", "type": "enum", "values": ["a","b"], "required": true,\n "description": "What kind of entry the row is"}`.\n Types: string, integer, number, boolean, date, datetime, enum, link, list (+ `items`), json.\n Attributes: required, default (`"{now}"`/`"{today}"`), min, max, step, values, `ordered` (enum in\n order: filters/avg use the position), ref (link target, full `catalog.schema.table` or "self"),\n unique, label, description, aliases, `generated` (e.g. `"date(occurred_at)"`, `"{name} {surname}"`),\n `identity` ("filename" | "created"), `vocabulary` (allowed values = names of another table\'s rows),\n `hierarchy: true` (one parent link to its own table), `acyclic: true` (links to rows of its own table that never loop back, such as tasks blocked by tasks; with `inverse`, the rule holds on both sides), `dense` (written on every row),\n `inverse` on a link column: the column of the `ref` table that links back (`friends` \u2194\n `friends`, `children` \u2194 `parents`, `partner` \u2194 `partner`); writes keep both sides in step.\n- `time_column`: rows named by that date/datetime; otherwise `filename` (e.g. `"{name}"`).\n- The table\'s options, as alter_table names them: `aliases` (how agents find it, with the\n description), `partition`, `exclude`, `archive`, `history` (keep its versions; default: the\n database\'s setting), `autolink_target` (true / false: may automatic links link its rows? default:\n yes, unless its rows are named by a date or a time, as with `time_column`).\n- `row_template`: markdown body of new rows. Shared columns come from bases: `set_table_bases`.\n- `instructions`: how to fill a row, for agents (Markdown); describe_table returns them.\n- `tags`: key/value labels of the table, strings (`{"domain": "health"}`); list_tables and\n describe_table return them, alter_table changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", \u2026}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\nGenerated aggregates of a json column holding a list of objects (integer or number columns; avg: number): `count(feeds)`, `count(feeds.min)` (the items with a min), `sum(feeds.min)`, `avg(\u2026)`, `min(\u2026)`, `max(\u2026)`, with an optional filter on one field: `count(feeds, side = "left")`, `sum(feeds.min, min > 0)` (=, !=, <, <=, >, >=; "text", a number, true or false). Recomputed on every write; no list: count and sum 0, avg/min/max empty; a field that is not a number: empty.\nFiltered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.\n\nThe schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).',
614
614
  "inputSchema": {
615
615
  "additionalProperties": false,
616
616
  "properties": {
@@ -1704,7 +1704,7 @@ var OPERATIONS = [
1704
1704
  },
1705
1705
  {
1706
1706
  "name": "add_column",
1707
- "description": 'Add a typed column. Sparse by default (written only on rows that have a value \u2014 use for\nmetrics, e.g. `{"name": "metric_mood", "type": "integer", "min": 1, "max": 5, "label":\n"Mood", "aliases": ["mood"], "description": "Mood of the day, 1 = bad, 5 = great"}`).\n`description` is required: what the column holds, for the agents and people who read the schema\n(the engine writes it for `identity` "uuid" / "created" columns).\n`dense: true` in the spec adds it to every row with its `default`. Call `describe_table` first: never add\na column whose meaning an existing column (name/label/aliases/description) already covers.\nColumn names are permanent identifiers; only `rename_column` changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", \u2026}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\nFiltered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.\nAcyclic links: `acyclic: true` on a link (or list of links) to the table itself refuses every write that closes a cycle, on either side of an `inverse`; refused while existing rows form one (they are listed).\n\nThe schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).',
1707
+ "description": 'Add a typed column. Sparse by default (written only on rows that have a value \u2014 use for\nmetrics, e.g. `{"name": "metric_mood", "type": "integer", "min": 1, "max": 5, "label":\n"Mood", "aliases": ["mood"], "description": "Mood of the day, 1 = bad, 5 = great"}`).\n`description` is required: what the column holds, for the agents and people who read the schema\n(the engine writes it for `identity` "uuid" / "created" columns).\n`dense: true` in the spec adds it to every row with its `default`. Call `describe_table` first: never add\na column whose meaning an existing column (name/label/aliases/description) already covers.\nColumn names are permanent identifiers; only `rename_column` changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{"stated": "the user said it", \u2026}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: "link({occurred_at:YYYY-MM-DD})"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\nGenerated aggregates of a json column holding a list of objects (integer or number columns; avg: number): `count(feeds)`, `count(feeds.min)` (the items with a min), `sum(feeds.min)`, `avg(\u2026)`, `min(\u2026)`, `max(\u2026)`, with an optional filter on one field: `count(feeds, side = "left")`, `sum(feeds.min, min > 0)` (=, !=, <, <=, >, >=; "text", a number, true or false). Recomputed on every write; no list: count and sum 0, avg/min/max empty; a field that is not a number: empty.\nFiltered link targets (link columns): `ref_where` (a `where` every target must match) and `ref_by` (a column of the row picks the target level: `{"column": "kind", "levels": ["area", "project", "workstream"]}` or `{"column": "kind", "map": {"area": null, "project": ["area"]}}`; null = top level, no link; `target_column` when the target names it differently: an enum target column must have every value the map allows, a string one takes any value). A link to no row of the table, or to the row itself, is refused too. Existing rows that break them refuse the change; `list_link_targets` lists the valid targets of a row.\nAcyclic links: `acyclic: true` on a link (or list of links) to the table itself refuses every write that closes a cycle, on either side of an `inverse`; refused while existing rows form one (they are listed).\n\nThe schema changes only through operations like this one: never edit metastore.yaml by hand (no validation, no undo).',
1708
1708
  "inputSchema": {
1709
1709
  "additionalProperties": false,
1710
1710
  "properties": {
@@ -5103,7 +5103,7 @@ var OPERATIONS = [
5103
5103
  },
5104
5104
  {
5105
5105
  "name": "describe_database",
5106
- "description": "Describe the database: its folder (`root`), `metastore` (`metastore.yaml`: read it freely,\nbut it is read-only for agents and changes only through the schema operations), configuration\n(default catalog and schema, row partition and file-name formats, archive folder, time zone,\nhistory, automatic links),\njournal folder, `bases` (shared column sets and the tables using them), `catalogs` \u2192 `schemas` \u2192 `tables` (with `row_count`, `tags`, and `unreadable_count` when some rows' front matter cannot be read) and `views`;\ncatalogs and schemas show their `comment` (set with `comment_on`). A table or base defined before\ndescriptions were required has `missing_descriptions`: what lacks one, for alter_table / alter_column\n(define_base for a base) to fill, so every table and column says what it holds.",
5106
+ "description": "Describe the database: its folder (`root`), `metastore` (`metastore.yaml`: read it freely,\nbut it is read-only for agents and changes only through the schema operations), configuration\n(default catalog and schema, row partition and file-name formats, archive folder, time zone,\nhistory, automatic links),\njournal folder, `bases` (shared column sets and the tables using them), `catalogs` \u2192 `schemas` \u2192 `tables` (with `row_count`, `tags`, and `unreadable_count` when some rows' front matter cannot be read) and `views`;\ncatalogs and schemas show their `comment` (set with `comment_on`). A table or base defined before\ndescriptions were required has `missing_descriptions`: what lacks one, for alter_table / alter_column\n(define_base for a base) to fill, so every table and column says what it holds.\nA token with `read` patterns sees only the tables, views and bases it may read.",
5107
5107
  "inputSchema": {
5108
5108
  "additionalProperties": false,
5109
5109
  "properties": {},
@@ -11667,6 +11667,141 @@ var OPERATIONS = [
11667
11667
  ]
11668
11668
  }
11669
11669
  },
11670
+ {
11671
+ "name": "search",
11672
+ "description": "Search the notes by their words and, when semantic search is on, by their meaning:\n`{query, results: [{path, table?, score, heading, snippet, matched_by}], meaning}`, one result per\nnote, best first. It always works: with semantic search off it ranks by words alone (BM25:\nrare words count more; a word in the note's name or properties counts more), with it on it fuses\nboth rankings (Reciprocal Rank Fusion), so a note found only by its words or only by its meaning\nis still there. `matched_by` says which (`words`, `meaning`); `meaning` is `on`, `off` or `failed`\n(the embedding provider failed: words only, `meaning_error` says why). Query syntax as search_docs:\n`\"a phrase\"` and `+word` must appear, `-word` must not (both rankings); words in any language,\ncase and accents ignored, no stemming. Filters: `tables` (qualified or short names), `folder`,\n`min_score` (the meaning ranking's cosine floor). `limit`: default 10, max 100. Then read_note /\nselect_rows for the details.",
11673
+ "inputSchema": {
11674
+ "additionalProperties": false,
11675
+ "properties": {
11676
+ "query": {
11677
+ "type": "string"
11678
+ },
11679
+ "limit": {
11680
+ "default": 10,
11681
+ "type": "integer"
11682
+ },
11683
+ "tables": {
11684
+ "anyOf": [
11685
+ {
11686
+ "items": {
11687
+ "type": "string"
11688
+ },
11689
+ "type": "array"
11690
+ },
11691
+ {
11692
+ "type": "null"
11693
+ }
11694
+ ],
11695
+ "default": null
11696
+ },
11697
+ "folder": {
11698
+ "anyOf": [
11699
+ {
11700
+ "type": "string"
11701
+ },
11702
+ {
11703
+ "type": "null"
11704
+ }
11705
+ ],
11706
+ "default": null
11707
+ },
11708
+ "min_score": {
11709
+ "anyOf": [
11710
+ {
11711
+ "type": "number"
11712
+ },
11713
+ {
11714
+ "type": "null"
11715
+ }
11716
+ ],
11717
+ "default": null
11718
+ }
11719
+ },
11720
+ "required": [
11721
+ "query"
11722
+ ],
11723
+ "type": "object"
11724
+ },
11725
+ "annotations": {
11726
+ "title": "Search",
11727
+ "readOnlyHint": true,
11728
+ "destructiveHint": false,
11729
+ "idempotentHint": true,
11730
+ "openWorldHint": false
11731
+ },
11732
+ "responseSchema": {
11733
+ "type": "object",
11734
+ "properties": {
11735
+ "query": {
11736
+ "type": "string"
11737
+ },
11738
+ "results": {
11739
+ "type": "array",
11740
+ "items": {
11741
+ "type": "object",
11742
+ "properties": {
11743
+ "path": {
11744
+ "type": "string"
11745
+ },
11746
+ "table": {
11747
+ "type": "string",
11748
+ "description": "Qualified table of a row note."
11749
+ },
11750
+ "score": {
11751
+ "type": "number",
11752
+ "description": "BM25 when ranked by words alone; the Reciprocal Rank Fusion score when fused."
11753
+ },
11754
+ "heading": {
11755
+ "type": "string",
11756
+ "description": "Heading above the match (empty before the first heading)."
11757
+ },
11758
+ "snippet": {
11759
+ "type": "string",
11760
+ "description": "About 200 characters around the first match, or the best passage by meaning."
11761
+ },
11762
+ "matched_by": {
11763
+ "type": "array",
11764
+ "items": {
11765
+ "type": "string",
11766
+ "enum": [
11767
+ "words",
11768
+ "meaning"
11769
+ ]
11770
+ },
11771
+ "description": "The rankings the note is in."
11772
+ }
11773
+ },
11774
+ "required": [
11775
+ "path",
11776
+ "score",
11777
+ "heading",
11778
+ "snippet",
11779
+ "matched_by"
11780
+ ]
11781
+ },
11782
+ "description": "One result per note, best first."
11783
+ },
11784
+ "meaning": {
11785
+ "type": "string",
11786
+ "enum": [
11787
+ "on",
11788
+ "off",
11789
+ "failed"
11790
+ ],
11791
+ "description": "on: words and meaning fused; off: semantic search is off, words only; failed: the embedding provider failed, words only."
11792
+ },
11793
+ "meaning_error": {
11794
+ "type": "string",
11795
+ "description": "Why the meaning ranking failed (with meaning: failed)."
11796
+ }
11797
+ },
11798
+ "required": [
11799
+ "query",
11800
+ "results",
11801
+ "meaning"
11802
+ ]
11803
+ }
11804
+ },
11670
11805
  {
11671
11806
  "name": "describe_semantic_index",
11672
11807
  "description": "The semantic search index: `enabled`, `provider`, `model`, `files`, `passages`, `pending`,\n`running`, `last_sync`, `last_error`. sync_semantic_index brings it up to date.",
@@ -17792,6 +17927,7 @@ var OPERATION_KIND = {
17792
17927
  list_folder: "queries",
17793
17928
  search_notes: "queries",
17794
17929
  semantic_search: "queries",
17930
+ search: "queries",
17795
17931
  graph_neighbors: "queries",
17796
17932
  graph_traverse: "queries",
17797
17933
  graph_path: "queries",