@notis_ai/cli 0.2.0-beta.136.1 → 0.2.0-beta.139.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.
- package/README.md +38 -0
- package/dist/agent-hooks/notis-agent-hook.mjs +16620 -0
- package/{skills → dist/base-skills}/notis-apps/SKILL.md +9 -6
- package/{skills → dist/base-skills}/notis-cli/SKILL.md +1 -1
- package/dist/base-skills/notis-query/SKILL.md +705 -0
- package/dist/scaffolds/notis-database/packages/sdk/src/config.ts +8 -0
- package/dist/scaffolds/notis-journal/packages/sdk/src/config.ts +8 -0
- package/dist/scaffolds/notis-notes/packages/sdk/src/config.ts +8 -0
- package/dist/scaffolds/notis-random/packages/sdk/src/config.ts +8 -0
- package/dist/skill-sync/index.js +1528 -0
- package/dist/skill-sync/index.js.map +7 -0
- package/package.json +4 -1
- package/skills/notis-cli/AGENT_INSTRUCTIONS.md +39 -0
- package/skills/notis-onboarding/BRIEF.md +16 -0
- package/src/agent-hook-entry.js +5 -0
- package/src/cli.js +23 -14
- package/src/command-specs/agents.js +392 -0
- package/src/command-specs/auth.js +16 -0
- package/src/command-specs/index.js +6 -0
- package/src/command-specs/onboarding.js +59 -2
- package/src/command-specs/skills.js +56 -0
- package/src/runtime/agent-memory-state.js +126 -0
- package/src/runtime/agent-setup.js +383 -0
- package/src/runtime/base-skills.d.ts +20 -0
- package/src/runtime/base-skills.js +167 -0
- package/src/runtime/skill-sync/cloud-client.ts +96 -0
- package/src/runtime/skill-sync/index.ts +644 -0
- package/src/runtime/skill-sync/local-scanner.ts +1046 -0
- package/src/runtime/skill-sync/symlink-manager.ts +383 -0
- package/src/runtime/skill-sync/sync-plan.ts +22 -0
- package/src/runtime/skill-sync/types.ts +103 -0
- package/src/runtime/skill-sync/write-cloud-skill.ts +50 -0
- package/src/runtime/store-screenshot.js +6 -1
- package/src/runtime/sync-skills.d.ts +37 -0
- package/src/runtime/sync-skills.js +215 -0
- package/template/packages/sdk/src/config.ts +8 -0
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: notis-query
|
|
3
|
+
description: Use when agents need to query native Notis databases with direct structured filters, sorts, and pagination through `LOCAL_NOTIS_DATABASE_QUERY`.
|
|
4
|
+
feature_flag: store
|
|
5
|
+
mcp_resource: true
|
|
6
|
+
mcp_tool_patterns: ["LOCAL_NOTIS_DATABASE_*"]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Notis Query Skill
|
|
10
|
+
|
|
11
|
+
Use this skill when the user wants to search, filter, sort, or page through records in a native Notis database and the task is best handled with structured criteria instead of semantic search.
|
|
12
|
+
|
|
13
|
+
This skill is the single source of truth for `LOCAL_NOTIS_DATABASE_QUERY`.
|
|
14
|
+
|
|
15
|
+
## Canonical contract source
|
|
16
|
+
|
|
17
|
+
For custom view runtime usage, the canonical contract is always MCP `tools/list` `inputSchema` for `LOCAL_NOTIS_DATABASE_QUERY`.
|
|
18
|
+
|
|
19
|
+
- Use `notisView.listTools()` (or MCP `tools/list`) to read the live schema.
|
|
20
|
+
- Use `notisView.callTool("LOCAL_NOTIS_DATABASE_QUERY", args)` (or MCP `tools/call`) with arguments that match that schema exactly.
|
|
21
|
+
- If this skill text and `inputSchema` ever differ, follow `inputSchema`.
|
|
22
|
+
|
|
23
|
+
This keeps query arguments aligned with the same tool definitions used by agent runtime and avoids maintaining duplicate schema formats.
|
|
24
|
+
|
|
25
|
+
## When to use `LOCAL_NOTIS_DATABASE_QUERY`
|
|
26
|
+
|
|
27
|
+
Use `LOCAL_NOTIS_DATABASE_QUERY` when:
|
|
28
|
+
|
|
29
|
+
- you already know the target native database
|
|
30
|
+
- the user wants structured filtering or sorting
|
|
31
|
+
- you need predictable pagination over database rows
|
|
32
|
+
- you need to find records before reading or updating a specific document
|
|
33
|
+
- you need to find matching records before calling `LOCAL_NOTIS_DATABASE_GET_DOCUMENT` or a generated database upsert tool
|
|
34
|
+
- the task should use direct database criteria instead of semantic memory search
|
|
35
|
+
|
|
36
|
+
Do not use `LOCAL_NOTIS_DATABASE_QUERY` when:
|
|
37
|
+
|
|
38
|
+
- the relevant database is unknown
|
|
39
|
+
- semantic search over broad workspace context is better
|
|
40
|
+
- the task points to one known document by `document_id` or portal URL
|
|
41
|
+
|
|
42
|
+
Use these tools together:
|
|
43
|
+
|
|
44
|
+
- `LOCAL_NOTIS_DATABASE_LIST_DATABASES` to discover available databases and confirm the slug
|
|
45
|
+
- `LOCAL_NOTIS_DATABASE_GET_DATABASE` to inspect read-only schema detail, ordered properties, options, and relation targets
|
|
46
|
+
- `LOCAL_NOTIS_DATABASE_QUERY` to find matching records
|
|
47
|
+
- `LOCAL_NOTIS_DATABASE_GET_DOCUMENT` to inspect one specific matching document in full
|
|
48
|
+
- generated database upsert tools to update or create records after you know the right document or relation IDs
|
|
49
|
+
|
|
50
|
+
Follow the same workflow and use the exact canonical tool names available in the current runtime.
|
|
51
|
+
|
|
52
|
+
## Native Database Workflow
|
|
53
|
+
|
|
54
|
+
### Listing databases
|
|
55
|
+
|
|
56
|
+
Use `LOCAL_NOTIS_DATABASE_LIST_DATABASES` (`notis_list_databases` in legacy
|
|
57
|
+
underscore-form references) when:
|
|
58
|
+
|
|
59
|
+
- you need to confirm which native databases exist
|
|
60
|
+
- you need the database ID or slug before querying or choosing an upsert tool
|
|
61
|
+
- you need database metadata such as name, description, or document counts
|
|
62
|
+
- the orchestrator asks what is available in the user's workspace
|
|
63
|
+
|
|
64
|
+
Always inspect the user's native Notis databases before creating schema updates or choosing where to save work.
|
|
65
|
+
|
|
66
|
+
### Creating databases
|
|
67
|
+
|
|
68
|
+
Use `LOCAL_NOTIS_DATABASE_UPSERT_DATABASE` (`notis_upsert_database` in legacy
|
|
69
|
+
underscore-form references) to create or update native databases.
|
|
70
|
+
|
|
71
|
+
Every native database must belong to a Notis app. When creating a database,
|
|
72
|
+
pass the owning app's slug or id in the `app` field; if the user has no
|
|
73
|
+
suitable app yet, create one first with `LOCAL_NOTIS_CREATE_APP`. Updates do
|
|
74
|
+
not need the `app` field.
|
|
75
|
+
|
|
76
|
+
Define schemas with appropriate property types:
|
|
77
|
+
|
|
78
|
+
- `title`
|
|
79
|
+
- `rich_text`
|
|
80
|
+
- `select`
|
|
81
|
+
- `multi_select`
|
|
82
|
+
- `status`
|
|
83
|
+
- `checkbox`
|
|
84
|
+
- `date`
|
|
85
|
+
- `number`
|
|
86
|
+
- `url`
|
|
87
|
+
- `email`
|
|
88
|
+
- `phone_number`
|
|
89
|
+
- `relation`
|
|
90
|
+
|
|
91
|
+
When adding or updating a `relation` property, always pass the target database explicitly with `database_id`. Do not rely on description text to imply the relation target.
|
|
92
|
+
|
|
93
|
+
Example relation update:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"operation": "update",
|
|
98
|
+
"database_id": "tasks-db-id",
|
|
99
|
+
"properties": [
|
|
100
|
+
{
|
|
101
|
+
"property_id": "prop_list",
|
|
102
|
+
"name": "List",
|
|
103
|
+
"action": "update",
|
|
104
|
+
"type": "relation",
|
|
105
|
+
"database_id": "lists-db-id",
|
|
106
|
+
"description": "Relation to Lists"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Reading documents
|
|
113
|
+
|
|
114
|
+
Use `LOCAL_NOTIS_DATABASE_GET_DOCUMENT` when:
|
|
115
|
+
|
|
116
|
+
- the task references a specific document by `document_id` or portal URL
|
|
117
|
+
- detailed content from a known document is needed
|
|
118
|
+
|
|
119
|
+
You may pass either a `document_id` or a portal URL such as `https://app.notis.ai/documents/abc123` or `/documents/abc123`.
|
|
120
|
+
|
|
121
|
+
## Native Document Handling
|
|
122
|
+
|
|
123
|
+
### Response requirements
|
|
124
|
+
|
|
125
|
+
- Always include the document title, database name, and a markdown portal link for any document you create or update.
|
|
126
|
+
- Never expose a raw `document_id` in your completion summary unless the user explicitly asked for it.
|
|
127
|
+
- Clearly state whether the document was created or updated.
|
|
128
|
+
- For updates, clearly state whether you replaced the original content or appended to the end.
|
|
129
|
+
|
|
130
|
+
### Upserting with relations
|
|
131
|
+
|
|
132
|
+
When upserting into a database that relates to another database, first query for the related record and use the returned `document_id` for the relation.
|
|
133
|
+
|
|
134
|
+
### Upserting complex documents
|
|
135
|
+
|
|
136
|
+
For copywriting-style work such as articles or social posts, try to find similar writing by the user and match the user's style and tone.
|
|
137
|
+
|
|
138
|
+
### Updating a document
|
|
139
|
+
|
|
140
|
+
1. Retrieve the current content with `LOCAL_NOTIS_DATABASE_GET_DOCUMENT`, `LOCAL_NOTIS_DATABASE_QUERY`, or `LOCAL_NOTIS_SEARCH_MEMORIES` with `memory_kind="native_document"`.
|
|
141
|
+
2. Use the relevant `LOCAL_NOTIS_DATABASE_UPSERT_<DATABASE_SLUG>` tool with the existing `document_id` so the document is updated instead of recreated.
|
|
142
|
+
3. For local edits to an existing document such as appending a bullet, inserting a paragraph, changing one section, or preserving structure, use `edit_mode = "block_operations"` instead of rewriting markdown.
|
|
143
|
+
4. When developer context includes a `<page_context ... resource_type="document" ...>` tag, treat that as the currently open document and fetch it before asking the user for any identifier again.
|
|
144
|
+
|
|
145
|
+
### Default upsert preferences
|
|
146
|
+
|
|
147
|
+
As long as they do not conflict with the user's intent, the existing document style, or the tool contract:
|
|
148
|
+
|
|
149
|
+
- Prefer updating existing documents over creating new ones when the user asked for a modification.
|
|
150
|
+
- Use `replace = true` to replace content and `replace = false` to append when you are in markdown mode.
|
|
151
|
+
- When the user asked to append, insert, tweak, or preserve the rest of an existing document, prefer `block_operations` with `insert_blocks`, `update_block`, `replace_blocks`, or `remove_blocks`.
|
|
152
|
+
- Do not use markdown rewrite mode for surgical edits unless block operations are genuinely impossible for the requested change.
|
|
153
|
+
- Reorganize messy thoughts into a clearer structure.
|
|
154
|
+
- Highlight essential concepts and extract action items.
|
|
155
|
+
- Format notes with markdown titles, subheadings, bold text, blockquotes, ordered lists, and unordered lists when helpful.
|
|
156
|
+
- Add useful insight, challenge weak reasoning, debunk false claims, or enrich the content when appropriate.
|
|
157
|
+
- Fill in missing information the user asked you to complete when the context supports it.
|
|
158
|
+
- Imitate the user's voice when you can infer it from semantic memory search with `memory_kind="native_document"` or existing document context.
|
|
159
|
+
- Save images in document content using standard markdown and in URL properties when relevant.
|
|
160
|
+
- Do not place videos inside document content. Store them only in media properties.
|
|
161
|
+
- Do not add a custom emoji or cover unless the user requested one.
|
|
162
|
+
|
|
163
|
+
## Supported execution mode
|
|
164
|
+
|
|
165
|
+
`LOCAL_NOTIS_DATABASE_QUERY` supports direct structured queries only.
|
|
166
|
+
|
|
167
|
+
Natural-language query generation is retired. Do not send free-form requests like "find overdue tasks from important clients"; build the structured `query` payload yourself.
|
|
168
|
+
|
|
169
|
+
## Request shape
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"database_id": "tasks-db-id",
|
|
174
|
+
"database_slug": "tasks",
|
|
175
|
+
"query": {
|
|
176
|
+
"filter": {
|
|
177
|
+
"operator": "and",
|
|
178
|
+
"conditions": [
|
|
179
|
+
{
|
|
180
|
+
"property": "Status",
|
|
181
|
+
"type": "status",
|
|
182
|
+
"operator": "equals",
|
|
183
|
+
"value": "In Progress"
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
"sorts": [
|
|
188
|
+
{
|
|
189
|
+
"property": "Due Date",
|
|
190
|
+
"direction": "ascending"
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
"page_size": 20
|
|
194
|
+
},
|
|
195
|
+
"offset": 0
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Top-level fields:
|
|
200
|
+
|
|
201
|
+
- One of `database_id` or `database_slug` is required.
|
|
202
|
+
- `database_id`: stable native database ID. Prefer this when it is available from database context, `list_databases`, or `get_database`.
|
|
203
|
+
- `database_slug`: native database slug. Use this when `database_id` is not available, or pass it alongside `database_id` as a fallback.
|
|
204
|
+
- `query`: required object
|
|
205
|
+
- `offset`: optional numeric pagination offset
|
|
206
|
+
|
|
207
|
+
When both `database_id` and `database_slug` are provided, they must identify the same database. If the ID is stale and no database is found by ID, the runtime may fall back to the slug.
|
|
208
|
+
|
|
209
|
+
`query` fields:
|
|
210
|
+
|
|
211
|
+
- `filter`: optional rule tree
|
|
212
|
+
- `sorts`: optional array of sort definitions
|
|
213
|
+
- `page_size`: optional integer page size
|
|
214
|
+
|
|
215
|
+
## Filter shape
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"operator": "and",
|
|
220
|
+
"conditions": [
|
|
221
|
+
{
|
|
222
|
+
"property": "Status",
|
|
223
|
+
"type": "status",
|
|
224
|
+
"operator": "equals",
|
|
225
|
+
"value": "In Progress"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"property": "Priority",
|
|
229
|
+
"type": "select",
|
|
230
|
+
"operator": "equals",
|
|
231
|
+
"value": "High"
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Use nested groups when needed:
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"operator": "or",
|
|
242
|
+
"conditions": [
|
|
243
|
+
{
|
|
244
|
+
"property": "Status",
|
|
245
|
+
"type": "status",
|
|
246
|
+
"operator": "equals",
|
|
247
|
+
"value": "Todo"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"operator": "and",
|
|
251
|
+
"conditions": [
|
|
252
|
+
{
|
|
253
|
+
"property": "Priority",
|
|
254
|
+
"type": "select",
|
|
255
|
+
"operator": "equals",
|
|
256
|
+
"value": "High"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"property": "Archived",
|
|
260
|
+
"type": "checkbox",
|
|
261
|
+
"operator": "equals",
|
|
262
|
+
"value": false
|
|
263
|
+
}
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Supported property semantics
|
|
271
|
+
|
|
272
|
+
Use the real Notis property name and the correct property type.
|
|
273
|
+
|
|
274
|
+
### Title and rich text
|
|
275
|
+
|
|
276
|
+
Recommended operators:
|
|
277
|
+
|
|
278
|
+
- `contains`
|
|
279
|
+
- `equals`
|
|
280
|
+
- `not_equals`
|
|
281
|
+
|
|
282
|
+
Example:
|
|
283
|
+
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"property": "Title",
|
|
287
|
+
"type": "title",
|
|
288
|
+
"operator": "contains",
|
|
289
|
+
"value": "launch"
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Select and status
|
|
294
|
+
|
|
295
|
+
Recommended operators:
|
|
296
|
+
|
|
297
|
+
- `equals`
|
|
298
|
+
- `not_equals`
|
|
299
|
+
- `in`
|
|
300
|
+
|
|
301
|
+
Example:
|
|
302
|
+
|
|
303
|
+
```json
|
|
304
|
+
{
|
|
305
|
+
"property": "Status",
|
|
306
|
+
"type": "status",
|
|
307
|
+
"operator": "equals",
|
|
308
|
+
"value": "Done"
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Multi-select
|
|
313
|
+
|
|
314
|
+
Recommended operators:
|
|
315
|
+
|
|
316
|
+
- `contains`
|
|
317
|
+
- `not_contains`
|
|
318
|
+
|
|
319
|
+
Example:
|
|
320
|
+
|
|
321
|
+
```json
|
|
322
|
+
{
|
|
323
|
+
"property": "Tags",
|
|
324
|
+
"type": "multi_select",
|
|
325
|
+
"operator": "contains",
|
|
326
|
+
"value": "Urgent"
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Checkbox
|
|
331
|
+
|
|
332
|
+
Recommended operator:
|
|
333
|
+
|
|
334
|
+
- `equals`
|
|
335
|
+
|
|
336
|
+
Example:
|
|
337
|
+
|
|
338
|
+
```json
|
|
339
|
+
{
|
|
340
|
+
"property": "Archived",
|
|
341
|
+
"type": "checkbox",
|
|
342
|
+
"operator": "equals",
|
|
343
|
+
"value": false
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Number
|
|
348
|
+
|
|
349
|
+
Recommended operators:
|
|
350
|
+
|
|
351
|
+
- `equals`
|
|
352
|
+
- `not_equals`
|
|
353
|
+
- `greater_than`
|
|
354
|
+
- `greater_than_or_equal`
|
|
355
|
+
- `less_than`
|
|
356
|
+
- `less_than_or_equal`
|
|
357
|
+
|
|
358
|
+
Example:
|
|
359
|
+
|
|
360
|
+
```json
|
|
361
|
+
{
|
|
362
|
+
"property": "Score",
|
|
363
|
+
"type": "number",
|
|
364
|
+
"operator": "greater_than_or_equal",
|
|
365
|
+
"value": 80
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Date
|
|
370
|
+
|
|
371
|
+
Recommended operators:
|
|
372
|
+
|
|
373
|
+
- `equals`
|
|
374
|
+
- `before`
|
|
375
|
+
- `after`
|
|
376
|
+
- `on_or_before`
|
|
377
|
+
- `on_or_after`
|
|
378
|
+
|
|
379
|
+
Use ISO dates or timestamps depending on the property precision.
|
|
380
|
+
|
|
381
|
+
Example:
|
|
382
|
+
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"property": "Due Date",
|
|
386
|
+
"type": "date",
|
|
387
|
+
"operator": "on_or_before",
|
|
388
|
+
"value": "2026-03-31"
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Relation
|
|
393
|
+
|
|
394
|
+
Recommended operators:
|
|
395
|
+
|
|
396
|
+
- `contains`
|
|
397
|
+
- `not_contains`
|
|
398
|
+
|
|
399
|
+
Pass the related `document_id`, not the display title.
|
|
400
|
+
|
|
401
|
+
Example:
|
|
402
|
+
|
|
403
|
+
```json
|
|
404
|
+
{
|
|
405
|
+
"property": "Project",
|
|
406
|
+
"type": "relation",
|
|
407
|
+
"operator": "contains",
|
|
408
|
+
"value": "doc_project_123"
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Formula
|
|
413
|
+
|
|
414
|
+
Treat formula values according to the returned data type. In practice, use the matching operator family for the computed result:
|
|
415
|
+
|
|
416
|
+
- text-like formula: `contains` or `equals`
|
|
417
|
+
- number-like formula: numeric comparison operators
|
|
418
|
+
- boolean-like formula: `equals`
|
|
419
|
+
|
|
420
|
+
Only use formula filters when the formula property already exists in the schema.
|
|
421
|
+
|
|
422
|
+
## Sorts
|
|
423
|
+
|
|
424
|
+
Sort objects look like this:
|
|
425
|
+
|
|
426
|
+
```json
|
|
427
|
+
{
|
|
428
|
+
"property": "Created At",
|
|
429
|
+
"direction": "descending"
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Recommended directions:
|
|
434
|
+
|
|
435
|
+
- `ascending`
|
|
436
|
+
- `descending`
|
|
437
|
+
|
|
438
|
+
Common sorts:
|
|
439
|
+
|
|
440
|
+
- title sorts for alphabetical browsing
|
|
441
|
+
- status then date sorts for workflow queues
|
|
442
|
+
- timestamp sorts such as `Created At`, `Updated At`, or `Last Edited Time`
|
|
443
|
+
|
|
444
|
+
Example:
|
|
445
|
+
|
|
446
|
+
```json
|
|
447
|
+
[
|
|
448
|
+
{
|
|
449
|
+
"property": "Last Edited Time",
|
|
450
|
+
"direction": "descending"
|
|
451
|
+
}
|
|
452
|
+
]
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Pagination
|
|
456
|
+
|
|
457
|
+
Use `page_size` to cap the number of results per call.
|
|
458
|
+
|
|
459
|
+
The response returns:
|
|
460
|
+
|
|
461
|
+
- `documents`
|
|
462
|
+
- `results_count`
|
|
463
|
+
- `has_more`
|
|
464
|
+
- `next_offset`
|
|
465
|
+
- `query`
|
|
466
|
+
- `complementary_instructions`
|
|
467
|
+
|
|
468
|
+
Pagination rules:
|
|
469
|
+
|
|
470
|
+
- start with `offset: 0` or omit it
|
|
471
|
+
- if `has_more` is true, call again with `offset: next_offset`
|
|
472
|
+
|
|
473
|
+
Example follow-up call:
|
|
474
|
+
|
|
475
|
+
```json
|
|
476
|
+
{
|
|
477
|
+
"database_id": "tasks-db-id",
|
|
478
|
+
"query": {
|
|
479
|
+
"page_size": 25
|
|
480
|
+
},
|
|
481
|
+
"offset": 25
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Response shape
|
|
486
|
+
|
|
487
|
+
The result includes database rows in `documents`. Each document usually contains:
|
|
488
|
+
|
|
489
|
+
- `document_id`
|
|
490
|
+
- title-like display fields
|
|
491
|
+
- matching property values
|
|
492
|
+
- metadata helpful for follow-up reads or updates
|
|
493
|
+
|
|
494
|
+
Use `document_id` from the query response when you need to:
|
|
495
|
+
|
|
496
|
+
- fetch full content with `LOCAL_NOTIS_DATABASE_GET_DOCUMENT`
|
|
497
|
+
- update a record with a generated database upsert tool
|
|
498
|
+
- attach it to a relation field in another upsert
|
|
499
|
+
|
|
500
|
+
## Examples
|
|
501
|
+
|
|
502
|
+
### Title or rich text contains
|
|
503
|
+
|
|
504
|
+
```json
|
|
505
|
+
{
|
|
506
|
+
"database_id": "notes-db-id",
|
|
507
|
+
"query": {
|
|
508
|
+
"filter": {
|
|
509
|
+
"operator": "and",
|
|
510
|
+
"conditions": [
|
|
511
|
+
{
|
|
512
|
+
"property": "Title",
|
|
513
|
+
"type": "title",
|
|
514
|
+
"operator": "contains",
|
|
515
|
+
"value": "pricing"
|
|
516
|
+
}
|
|
517
|
+
]
|
|
518
|
+
},
|
|
519
|
+
"page_size": 10
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Select or status equals
|
|
525
|
+
|
|
526
|
+
```json
|
|
527
|
+
{
|
|
528
|
+
"database_id": "tasks-db-id",
|
|
529
|
+
"query": {
|
|
530
|
+
"filter": {
|
|
531
|
+
"operator": "and",
|
|
532
|
+
"conditions": [
|
|
533
|
+
{
|
|
534
|
+
"property": "Status",
|
|
535
|
+
"type": "status",
|
|
536
|
+
"operator": "equals",
|
|
537
|
+
"value": "In Progress"
|
|
538
|
+
}
|
|
539
|
+
]
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Multi-select contains
|
|
546
|
+
|
|
547
|
+
```json
|
|
548
|
+
{
|
|
549
|
+
"database_id": "content-db-id",
|
|
550
|
+
"query": {
|
|
551
|
+
"filter": {
|
|
552
|
+
"operator": "and",
|
|
553
|
+
"conditions": [
|
|
554
|
+
{
|
|
555
|
+
"property": "Tags",
|
|
556
|
+
"type": "multi_select",
|
|
557
|
+
"operator": "contains",
|
|
558
|
+
"value": "Newsletter"
|
|
559
|
+
}
|
|
560
|
+
]
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### Checkbox equals
|
|
567
|
+
|
|
568
|
+
```json
|
|
569
|
+
{
|
|
570
|
+
"database_id": "tasks-db-id",
|
|
571
|
+
"query": {
|
|
572
|
+
"filter": {
|
|
573
|
+
"operator": "and",
|
|
574
|
+
"conditions": [
|
|
575
|
+
{
|
|
576
|
+
"property": "Completed",
|
|
577
|
+
"type": "checkbox",
|
|
578
|
+
"operator": "equals",
|
|
579
|
+
"value": true
|
|
580
|
+
}
|
|
581
|
+
]
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### Number comparison
|
|
588
|
+
|
|
589
|
+
```json
|
|
590
|
+
{
|
|
591
|
+
"database_id": "deals-db-id",
|
|
592
|
+
"query": {
|
|
593
|
+
"filter": {
|
|
594
|
+
"operator": "and",
|
|
595
|
+
"conditions": [
|
|
596
|
+
{
|
|
597
|
+
"property": "Amount",
|
|
598
|
+
"type": "number",
|
|
599
|
+
"operator": "greater_than",
|
|
600
|
+
"value": 10000
|
|
601
|
+
}
|
|
602
|
+
]
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### Date comparison
|
|
609
|
+
|
|
610
|
+
```json
|
|
611
|
+
{
|
|
612
|
+
"database_id": "tasks-db-id",
|
|
613
|
+
"query": {
|
|
614
|
+
"filter": {
|
|
615
|
+
"operator": "and",
|
|
616
|
+
"conditions": [
|
|
617
|
+
{
|
|
618
|
+
"property": "Due Date",
|
|
619
|
+
"type": "date",
|
|
620
|
+
"operator": "on_or_after",
|
|
621
|
+
"value": "2026-03-01"
|
|
622
|
+
}
|
|
623
|
+
]
|
|
624
|
+
},
|
|
625
|
+
"sorts": [
|
|
626
|
+
{
|
|
627
|
+
"property": "Due Date",
|
|
628
|
+
"direction": "ascending"
|
|
629
|
+
}
|
|
630
|
+
]
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### Relation contains
|
|
636
|
+
|
|
637
|
+
```json
|
|
638
|
+
{
|
|
639
|
+
"database_id": "tasks-db-id",
|
|
640
|
+
"query": {
|
|
641
|
+
"filter": {
|
|
642
|
+
"operator": "and",
|
|
643
|
+
"conditions": [
|
|
644
|
+
{
|
|
645
|
+
"property": "Project",
|
|
646
|
+
"type": "relation",
|
|
647
|
+
"operator": "contains",
|
|
648
|
+
"value": "doc_project_123"
|
|
649
|
+
}
|
|
650
|
+
]
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Timestamp sort
|
|
657
|
+
|
|
658
|
+
```json
|
|
659
|
+
{
|
|
660
|
+
"database_id": "tasks-db-id",
|
|
661
|
+
"query": {
|
|
662
|
+
"sorts": [
|
|
663
|
+
{
|
|
664
|
+
"property": "Last Edited Time",
|
|
665
|
+
"direction": "descending"
|
|
666
|
+
}
|
|
667
|
+
],
|
|
668
|
+
"page_size": 20
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Pagination follow-up
|
|
674
|
+
|
|
675
|
+
First call:
|
|
676
|
+
|
|
677
|
+
```json
|
|
678
|
+
{
|
|
679
|
+
"database_id": "tasks-db-id",
|
|
680
|
+
"query": {
|
|
681
|
+
"page_size": 20
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
Second call after a response with `has_more: true` and `next_offset: 20`:
|
|
687
|
+
|
|
688
|
+
```json
|
|
689
|
+
{
|
|
690
|
+
"database_id": "tasks-db-id",
|
|
691
|
+
"query": {
|
|
692
|
+
"page_size": 20
|
|
693
|
+
},
|
|
694
|
+
"offset": 20
|
|
695
|
+
}
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
## Practical workflow
|
|
699
|
+
|
|
700
|
+
1. Call `LOCAL_NOTIS_DATABASE_LIST_DATABASES` if you do not know the database ID yet.
|
|
701
|
+
2. Call `LOCAL_NOTIS_DATABASE_GET_DATABASE` if you need schema detail before building filters or relation payloads.
|
|
702
|
+
3. Call `LOCAL_NOTIS_DATABASE_QUERY` with `database_id` plus structured filters and sorts. Use `database_slug` only when the ID is not available.
|
|
703
|
+
4. If you need the full body of one row, call `LOCAL_NOTIS_DATABASE_GET_DOCUMENT` with the returned `document_id`.
|
|
704
|
+
5. If you need to update one of the matched rows, call the relevant generated database upsert tool with that `document_id`.
|
|
705
|
+
6. If you need a relation value, query the related database first and pass the resulting `document_id` into the upsert.
|
|
@@ -209,6 +209,14 @@ export interface NotisAppConfig {
|
|
|
209
209
|
*/
|
|
210
210
|
capabilities?: NotisAppCapabilities;
|
|
211
211
|
routes?: NotisRouteConfig[];
|
|
212
|
+
/**
|
|
213
|
+
* Final tool names this app can call at runtime, enforced server-side. Use
|
|
214
|
+
* names returned by shared discovery, including native `LOCAL_NOTIS_*`,
|
|
215
|
+
* connected-service names such as `GMAIL_SEND_EMAIL`,
|
|
216
|
+
* `LOCAL_POSTFORME_*`, and `LOCAL_MCP_<SERVER>_<TOOL>`. App code calls
|
|
217
|
+
* each declared name directly with `useTool`; metered calls use the shared
|
|
218
|
+
* credit-cap and usage-billing path.
|
|
219
|
+
*/
|
|
212
220
|
tools?: string[];
|
|
213
221
|
/** Skills shipped from this app's source tree. */
|
|
214
222
|
skills?: NotisAppSkillConfig[];
|