@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.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/CHANGELOG.md +10 -0
- package/corpus/templates/assets/CHANGELOG.md +8 -0
- package/corpus/templates/calendar/CHANGELOG.md +18 -0
- package/corpus/templates/clips/CHANGELOG.md +19 -0
- package/corpus/templates/content/CHANGELOG.md +16 -0
- package/corpus/templates/content/actions/_database-property-setup.ts +33 -2
- package/corpus/templates/content/actions/_database-setup-discovery.ts +4 -4
- package/corpus/templates/content/actions/_property-utils.ts +9 -1
- package/corpus/templates/content/actions/_relation-values.ts +291 -0
- package/corpus/templates/content/actions/configure-document-property.ts +53 -1
- package/corpus/templates/content/actions/search-content-database-rows.ts +124 -0
- package/corpus/templates/content/actions/set-document-property.ts +21 -1
- package/corpus/templates/content/agent-native.config.ts +5 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +892 -189
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +7 -2
- package/corpus/templates/content/app/components/editor/database/navigation-state.ts +4 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +16 -2
- package/corpus/templates/content/app/hooks/use-document-properties.ts +65 -5
- package/corpus/templates/content/app/i18n-data.ts +28 -0
- package/corpus/templates/content/changelog/2026-09-28-link-rows-across-collections-with-relation-properties.md +6 -0
- package/corpus/templates/content/changelog/2026-09-29-related-pages-can-be-loaded-past-the-first-25-results.md +6 -0
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +1 -0
- package/corpus/templates/content/shared/api.ts +21 -0
- package/corpus/templates/content/shared/properties.ts +19 -0
- package/corpus/templates/crm/CHANGELOG.md +8 -0
- package/corpus/templates/design/CHANGELOG.md +33 -0
- package/corpus/templates/design/actions/clone-creative-context-design-native.ts +12 -3
- package/corpus/templates/design/actions/generate-design.ts +2 -29
- package/corpus/templates/design/actions/update-design.ts +33 -8
- package/corpus/templates/design/app/components/design/design-canvas/LocalNetworkAccessPrompt.tsx +2 -2
- package/corpus/templates/design/changelog/2026-09-29-design-tweak-controls-stay-intact-when-an-edit-contains-inva.md +6 -0
- package/corpus/templates/design/changelog/2026-09-29-the-chrome-fallback-guide-shows-the-local-network-allow-opti.md +6 -0
- package/corpus/templates/design/shared/tweak-definition-schema.ts +30 -0
- package/corpus/templates/dispatch/CHANGELOG.md +4 -0
- package/corpus/templates/mail/CHANGELOG.md +34 -0
- package/corpus/templates/mail/app/components/email/EmailList.tsx +29 -11
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +4 -4
- package/corpus/templates/mail/app/pages/InboxPage.tsx +34 -10
- package/corpus/templates/mail/changelog/2026-09-29-mail-loading-layout.md +6 -0
- package/corpus/templates/slides/CHANGELOG.md +19 -0
- package/dist/automation/index.d.ts +1 -1
- package/dist/client/AppShellSkeleton.js +97 -54
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +7 -7
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/triggers/actions/manage-automation.d.ts +2 -2
- package/docs/content/versioning-and-stability.mdx +3 -2
- 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
|
-
|
|
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;
|