@agent-native/core 0.197.0-nightly-20260929180759 → 0.197.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 (55) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/CHANGELOG.md +10 -0
  3. package/corpus/templates/assets/CHANGELOG.md +8 -0
  4. package/corpus/templates/calendar/CHANGELOG.md +18 -0
  5. package/corpus/templates/clips/CHANGELOG.md +19 -0
  6. package/corpus/templates/content/CHANGELOG.md +16 -0
  7. package/corpus/templates/content/actions/_database-property-setup.ts +33 -2
  8. package/corpus/templates/content/actions/_database-setup-discovery.ts +4 -4
  9. package/corpus/templates/content/actions/_property-utils.ts +9 -1
  10. package/corpus/templates/content/actions/_relation-values.ts +291 -0
  11. package/corpus/templates/content/actions/configure-document-property.ts +53 -1
  12. package/corpus/templates/content/actions/search-content-database-rows.ts +124 -0
  13. package/corpus/templates/content/actions/set-document-property.ts +21 -1
  14. package/corpus/templates/content/agent-native.config.ts +5 -0
  15. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +892 -189
  16. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +7 -2
  17. package/corpus/templates/content/app/components/editor/database/navigation-state.ts +4 -1
  18. package/corpus/templates/content/app/hooks/use-content-database.ts +16 -2
  19. package/corpus/templates/content/app/hooks/use-document-properties.ts +65 -5
  20. package/corpus/templates/content/app/i18n-data.ts +28 -0
  21. package/corpus/templates/content/changelog/2026-09-28-link-rows-across-collections-with-relation-properties.md +6 -0
  22. package/corpus/templates/content/changelog/2026-09-29-related-pages-can-be-loaded-past-the-first-25-results.md +6 -0
  23. package/corpus/templates/content/parity/matrix.md +1 -1
  24. package/corpus/templates/content/parity/matrix.ts +1 -0
  25. package/corpus/templates/content/shared/api.ts +21 -0
  26. package/corpus/templates/content/shared/properties.ts +19 -0
  27. package/corpus/templates/crm/CHANGELOG.md +8 -0
  28. package/corpus/templates/design/CHANGELOG.md +33 -0
  29. package/corpus/templates/design/actions/clone-creative-context-design-native.ts +12 -3
  30. package/corpus/templates/design/actions/generate-design.ts +2 -29
  31. package/corpus/templates/design/actions/update-design.ts +33 -8
  32. package/corpus/templates/design/app/components/design/design-canvas/LocalNetworkAccessPrompt.tsx +2 -2
  33. package/corpus/templates/design/changelog/2026-09-29-design-tweak-controls-stay-intact-when-an-edit-contains-inva.md +6 -0
  34. package/corpus/templates/design/changelog/2026-09-29-the-chrome-fallback-guide-shows-the-local-network-allow-opti.md +6 -0
  35. package/corpus/templates/design/shared/tweak-definition-schema.ts +30 -0
  36. package/corpus/templates/dispatch/CHANGELOG.md +4 -0
  37. package/corpus/templates/mail/CHANGELOG.md +34 -0
  38. package/corpus/templates/mail/app/components/email/EmailList.tsx +29 -11
  39. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +4 -4
  40. package/corpus/templates/mail/app/pages/InboxPage.tsx +34 -10
  41. package/corpus/templates/mail/changelog/2026-09-29-mail-loading-layout.md +6 -0
  42. package/corpus/templates/slides/CHANGELOG.md +19 -0
  43. package/dist/automation/index.d.ts +1 -1
  44. package/dist/client/AppShellSkeleton.js +97 -54
  45. package/dist/collab/awareness.d.ts +2 -2
  46. package/dist/collab/struct-routes.d.ts +1 -1
  47. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  48. package/dist/notifications/routes.d.ts +2 -2
  49. package/dist/observability/routes.d.ts +7 -7
  50. package/dist/secrets/routes.d.ts +6 -6
  51. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  52. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  53. package/dist/triggers/actions/manage-automation.d.ts +2 -2
  54. package/docs/content/versioning-and-stability.mdx +3 -2
  55. package/package.json +4 -4
@@ -0,0 +1,124 @@
1
+ import { defineAction } from "@agent-native/core/action";
2
+ import { assertAccess } from "@agent-native/core/sharing";
3
+ import { and, asc, count, eq, isNull, sql } from "drizzle-orm";
4
+ import { z } from "zod";
5
+
6
+ import { getDb, schema } from "../server/db/index.js";
7
+ import { getDatabaseMutationContract } from "./_database-row-mutation.js";
8
+ import { resolveContentDatabaseRead } from "./_database-utils.js";
9
+ import { documentDiscoveryPagination } from "./_document-discovery-query.js";
10
+
11
+ function escapeLike(s: string): string {
12
+ return s.replace(/([\\%_])/g, "\\$1");
13
+ }
14
+
15
+ export default defineAction({
16
+ description:
17
+ "Search one Content collection's rows by title. Returns row document IDs to use as relation property values, in collection order, with explicit pagination.",
18
+ mcpTool: true,
19
+ schema: z.object({
20
+ databaseId: z.string().min(1).describe("Exact Content collection ID"),
21
+ query: z
22
+ .string()
23
+ .max(200)
24
+ .optional()
25
+ .describe("Optional case-insensitive title search text"),
26
+ limit: z.coerce.number().int().min(1).max(50).default(25),
27
+ offset: z.coerce.number().int().min(0).default(0),
28
+ }),
29
+ http: { method: "GET" },
30
+ run: async (args) => {
31
+ const resolution = await resolveContentDatabaseRead({
32
+ databaseId: args.databaseId,
33
+ });
34
+ if (!resolution.available) throw new Error(resolution.message);
35
+ const database = resolution.database;
36
+ if (database.systemRole) {
37
+ throw new Error("System collections cannot be linked.");
38
+ }
39
+
40
+ const db = getDb();
41
+ const query = args.query?.trim().toLowerCase() ?? "";
42
+ const where = and(
43
+ eq(schema.contentDatabaseItems.databaseId, database.id),
44
+ isNull(schema.documents.trashedAt),
45
+ query
46
+ ? sql`lower(${schema.documents.title}) like ${`%${escapeLike(query)}%`} escape '\\'`
47
+ : undefined,
48
+ );
49
+ const rows = await db
50
+ .select({
51
+ documentId: schema.documents.id,
52
+ title: schema.documents.title,
53
+ icon: schema.documents.icon,
54
+ })
55
+ .from(schema.contentDatabaseItems)
56
+ .innerJoin(
57
+ schema.documents,
58
+ eq(schema.documents.id, schema.contentDatabaseItems.documentId),
59
+ )
60
+ .where(where)
61
+ .orderBy(
62
+ asc(schema.contentDatabaseItems.position),
63
+ asc(schema.contentDatabaseItems.id),
64
+ )
65
+ .limit(args.limit)
66
+ .offset(args.offset);
67
+ const [total] = await db
68
+ .select({ value: count() })
69
+ .from(schema.contentDatabaseItems)
70
+ .innerJoin(
71
+ schema.documents,
72
+ eq(schema.documents.id, schema.contentDatabaseItems.documentId),
73
+ )
74
+ .where(where);
75
+
76
+ // Editors may create a new row from the picker; hand them the target and
77
+ // schema revision add-database-item needs.
78
+ let rowCreation: {
79
+ target: Awaited<ReturnType<typeof getDatabaseMutationContract>>["target"];
80
+ schemaRevision: string;
81
+ } | null = null;
82
+ if (database.spaceId) {
83
+ const canEdit = await assertAccess(
84
+ "document",
85
+ database.documentId,
86
+ "editor",
87
+ ).then(
88
+ () => true,
89
+ () => false,
90
+ );
91
+ if (canEdit) {
92
+ const contract = await getDatabaseMutationContract({
93
+ spaceId: database.spaceId,
94
+ databaseId: database.id,
95
+ databaseDocumentId: database.documentId,
96
+ authorityScope: database.orgId
97
+ ? { kind: "organization", id: database.orgId }
98
+ : { kind: "personal", id: database.ownerEmail },
99
+ });
100
+ rowCreation = {
101
+ target: contract.target,
102
+ schemaRevision: contract.schemaRevision,
103
+ };
104
+ }
105
+ }
106
+
107
+ return {
108
+ databaseId: database.id,
109
+ databaseDocumentId: database.documentId,
110
+ rowCreation,
111
+ rows: rows.map((row) => ({
112
+ documentId: row.documentId,
113
+ title: row.title || "Untitled",
114
+ icon: row.icon ?? null,
115
+ })),
116
+ pagination: documentDiscoveryPagination({
117
+ offset: args.offset,
118
+ limit: args.limit,
119
+ totalItems: Number(total?.value ?? 0),
120
+ returnedItems: rows.length,
121
+ }),
122
+ };
123
+ },
124
+ });
@@ -12,6 +12,8 @@ import {
12
12
  isComputedPropertyType,
13
13
  normalizePropertyValue,
14
14
  parsePropertyOptions,
15
+ parsePropertyValue,
16
+ serializePropertyValue,
15
17
  type DocumentPropertyType,
16
18
  } from "../shared/properties.js";
17
19
  import { contentDatabaseSourceFieldsAllowLocalWrite } from "../shared/source-field-policy.js";
@@ -28,6 +30,7 @@ import {
28
30
  nanoid,
29
31
  normalizedValueJson,
30
32
  } from "./_property-utils.js";
33
+ import { validateRelationWrite } from "./_relation-values.js";
31
34
 
32
35
  async function assertPropertyWritableByRowMutation(
33
36
  db: ReturnType<typeof getDb>,
@@ -276,7 +279,7 @@ export default defineAction({
276
279
  };
277
280
  }
278
281
 
279
- const valueJson = normalizedValueJson(type, value);
282
+ let valueJson = normalizedValueJson(type, value);
280
283
  await db.transaction(async (tx) => {
281
284
  await lockContentDatabaseMutation(
282
285
  tx as unknown as ReturnType<typeof getDb>,
@@ -337,6 +340,23 @@ export default defineAction({
337
340
  database.id,
338
341
  lockedDefinition,
339
342
  );
343
+ if (lockedType === "relation") {
344
+ const [stored] = await tx
345
+ .select({ valueJson: schema.documentPropertyValues.valueJson })
346
+ .from(schema.documentPropertyValues)
347
+ .where(
348
+ and(
349
+ eq(schema.documentPropertyValues.documentId, documentId),
350
+ eq(schema.documentPropertyValues.propertyId, propertyId),
351
+ ),
352
+ );
353
+ const ids = await validateRelationWrite(tx, {
354
+ definition: lockedDefinition,
355
+ nextValue: value,
356
+ previousValue: parsePropertyValue(stored?.valueJson),
357
+ });
358
+ valueJson = serializePropertyValue(ids);
359
+ }
340
360
  const isNaturalKey = lockedDatabase.naturalKeyPropertyId === propertyId;
341
361
  if (isNaturalKey) {
342
362
  let parsed: unknown;
@@ -0,0 +1,5 @@
1
+ import { defineAgentNativeConfig } from "@agent-native/core/config";
2
+
3
+ export default defineAgentNativeConfig({
4
+ changelog: { enabled: true },
5
+ });