@agent-native/core 0.164.11 → 0.164.15

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 (106) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +84 -0
  3. package/corpus/templates/calendar/AGENTS.md +5 -0
  4. package/corpus/templates/calendar/actions/delete-event.ts +1 -1
  5. package/corpus/templates/calendar/actions/delete-events.ts +508 -0
  6. package/corpus/templates/calendar/actions/event-action-helpers.ts +1 -1
  7. package/corpus/templates/calendar/actions/list-events.ts +53 -0
  8. package/corpus/templates/calendar/changelog/2026-08-18-the-agent-can-now-remove-many-meetings-at-once-such-as-every.md +6 -0
  9. package/corpus/templates/calendar/server/lib/event-weekday.ts +112 -0
  10. package/corpus/templates/content/actions/_database-source-utils.ts +25 -2
  11. package/corpus/templates/content/actions/_database-utils.ts +2 -0
  12. package/corpus/templates/content/actions/_local-folder-source.ts +186 -2
  13. package/corpus/templates/content/actions/connect-local-folder-source.ts +23 -8
  14. package/corpus/templates/content/actions/disconnect-local-folder-source.ts +3 -3
  15. package/corpus/templates/content/actions/resolve-local-folder-conflict.ts +2 -2
  16. package/corpus/templates/content/actions/sync-local-folder-source.ts +130 -12
  17. package/corpus/templates/content/app/components/LocalFolderLiveSync.tsx +77 -0
  18. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +354 -8
  19. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +23 -1
  20. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +78 -1
  21. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +36 -0
  22. package/corpus/templates/content/app/components/editor/local-source-write-state.ts +52 -0
  23. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +244 -6
  24. package/corpus/templates/content/app/components/sidebar/local-source-hierarchy.ts +189 -0
  25. package/corpus/templates/content/app/hooks/use-create-page.ts +26 -4
  26. package/corpus/templates/content/app/hooks/use-documents.ts +83 -0
  27. package/corpus/templates/content/app/i18n-data.ts +79 -0
  28. package/corpus/templates/content/app/lib/desktop-content-files.ts +57 -1
  29. package/corpus/templates/content/app/lib/local-content-source-files.ts +210 -34
  30. package/corpus/templates/content/app/lib/local-folder-live-sync.ts +191 -0
  31. package/corpus/templates/content/app/root.tsx +2 -1
  32. package/corpus/templates/content/app/routes/_app.local-files.tsx +103 -38
  33. package/corpus/templates/content/docs/product/capabilities/content.source.file-folder.md +2 -2
  34. package/corpus/templates/content/docs/product/features/content.feature.bring-your-local-work.md +3 -3
  35. package/corpus/templates/content/docs/product/roadmap.md +2 -2
  36. package/corpus/templates/content/docs/solutions/2026-08-18-content-navigation-coherence-shape.md +482 -0
  37. package/corpus/templates/content/shared/api.ts +25 -0
  38. package/corpus/templates/factory/AGENTS.md +2 -1
  39. package/corpus/templates/factory/actions/get-factory-graph-version.ts +69 -0
  40. package/corpus/templates/factory/actions/list-factory-graph-versions.ts +82 -0
  41. package/corpus/templates/factory/actions/restore-factory-graph-version.ts +163 -0
  42. package/corpus/templates/factory/actions/save-factory-graph.ts +93 -60
  43. package/corpus/templates/factory/app/components/factory/FactoryHistoryView.tsx +709 -0
  44. package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +62 -2
  45. package/corpus/templates/factory/app/components/ui/alert-dialog.tsx +1 -0
  46. package/corpus/templates/factory/app/i18n/en-US.ts +43 -0
  47. package/corpus/templates/factory/app/routes/factory.tsx +115 -15
  48. package/corpus/templates/factory/server/plugins/agent-chat.ts +3 -1
  49. package/dist/app-config/auth.d.ts +4 -0
  50. package/dist/app-config/auth.js +7 -0
  51. package/dist/app-config/schema.d.ts +3 -0
  52. package/dist/app-config/schema.js +2 -0
  53. package/dist/cli/code-agent-executor.js +6 -1
  54. package/dist/cli/code-agent-mcp-config.d.ts +2 -2
  55. package/dist/cli/code-agent-mcp-config.js +34 -9
  56. package/dist/client/org/OrgSwitcher.js +8 -4
  57. package/dist/collab/awareness.d.ts +2 -2
  58. package/dist/collab/routes.d.ts +1 -1
  59. package/dist/collab/struct-routes.d.ts +1 -1
  60. package/dist/mcp-client/config.d.ts +11 -0
  61. package/dist/mcp-client/config.js +33 -26
  62. package/dist/notifications/routes.d.ts +3 -3
  63. package/dist/observability/routes.d.ts +3 -3
  64. package/dist/progress/routes.d.ts +1 -1
  65. package/dist/resources/handlers.d.ts +2 -2
  66. package/dist/secrets/routes.d.ts +9 -9
  67. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  68. package/dist/server/auth.js +15 -1
  69. package/dist/server/realtime-token.d.ts +1 -1
  70. package/docs/content/actions-access-control.mdx +136 -2
  71. package/docs/content/actions-agent-tools.mdx +101 -0
  72. package/docs/content/actions-defining.mdx +2 -2
  73. package/docs/content/audit-log.mdx +1 -1
  74. package/docs/content/authentication.mdx +1 -1
  75. package/docs/content/cloudflare.mdx +43 -0
  76. package/docs/content/creating-templates.mdx +1 -1
  77. package/docs/content/deploy-an-app.mdx +109 -0
  78. package/docs/content/deployment-environment-variables.mdx +101 -0
  79. package/docs/content/deployment.mdx +125 -792
  80. package/docs/content/docs-components.mdx +2 -2
  81. package/docs/content/environment-variables.mdx +41 -41
  82. package/docs/content/file-uploads.mdx +74 -40
  83. package/docs/content/harness-agents.mdx +2 -2
  84. package/docs/content/internationalization.mdx +61 -65
  85. package/docs/content/key-concepts.mdx +3 -3
  86. package/docs/content/multi-app-workspace.mdx +2 -2
  87. package/docs/content/netlify.mdx +47 -0
  88. package/docs/content/node-docker.mdx +138 -0
  89. package/docs/content/organizations-teams-permissions.mdx +5 -5
  90. package/docs/content/other-platforms.mdx +27 -0
  91. package/docs/content/ssr-caching.mdx +45 -0
  92. package/docs/content/template-assets-developers.mdx +2 -2
  93. package/docs/content/template-chat-developers.mdx +2 -2
  94. package/docs/content/template-content-developers.mdx +2 -2
  95. package/docs/content/{local-file-mode.mdx → template-content-local-files.mdx} +2 -1
  96. package/docs/content/template-content-sync.mdx +2 -2
  97. package/docs/content/toolkit-agent-ux.mdx +1 -1
  98. package/docs/content/toolkit-resources.mdx +2 -2
  99. package/docs/content/updating-ui-in-production.mdx +35 -0
  100. package/docs/content/vercel.mdx +38 -0
  101. package/docs/content/what-is-agent-native.mdx +1 -1
  102. package/docs/content/workspace-deployment.mdx +350 -0
  103. package/package.json +1 -1
  104. package/docs/content/agents.mdx +0 -9
  105. package/docs/content/database.mdx +0 -317
  106. package/docs/content/human-approval.mdx +0 -156
@@ -0,0 +1,163 @@
1
+ import { defineAction } from "@agent-native/core/action";
2
+ import { buildDeepLink } from "@agent-native/core/server";
3
+ import { and, eq } from "drizzle-orm";
4
+ import { z } from "zod";
5
+
6
+ import { getDb } from "../server/db/index.js";
7
+ import {
8
+ factoryDefinitions,
9
+ factoryGraphVersions,
10
+ } from "../server/db/schema.js";
11
+ import { normalizeFactoryGraph } from "../server/factory-graph/contracts.js";
12
+ import {
13
+ DEFAULT_FACTORY_ID,
14
+ parseFactoryGraph,
15
+ } from "../server/factory-graph/store.js";
16
+ import {
17
+ requireWorkspaceMember,
18
+ workspaceMemberIdentityFromContext,
19
+ } from "../server/lib/require-workspace-member.js";
20
+ import { stableId } from "../server/triage/ids.js";
21
+
22
+ export default defineAction({
23
+ description:
24
+ "Restore a Factory visual graph version. Restoring never deletes history: it validates the selected snapshot, appends it as a new version, and makes that new version current while preserving the Factory prompt.",
25
+ schema: z.object({
26
+ factoryId: z
27
+ .string()
28
+ .trim()
29
+ .min(1)
30
+ .max(120)
31
+ .regex(/^[a-z0-9][a-z0-9-]*$/)
32
+ .default(DEFAULT_FACTORY_ID),
33
+ versionId: z.string().trim().min(1).max(240),
34
+ }),
35
+ link: ({ result }) => ({
36
+ url: buildDeepLink({
37
+ app: "factory",
38
+ view: "factory",
39
+ params: { factoryId: result.factoryId, tab: "history" },
40
+ }),
41
+ label: `Open ${result.name} history in Factory`,
42
+ }),
43
+ run: async ({ factoryId, versionId }, context) => {
44
+ const { userEmail, orgId } = await requireWorkspaceMember(
45
+ workspaceMemberIdentityFromContext(context),
46
+ );
47
+ const db = getDb();
48
+
49
+ return db.transaction(async (tx) => {
50
+ const definition = (
51
+ await tx
52
+ .select()
53
+ .from(factoryDefinitions)
54
+ .where(
55
+ and(
56
+ eq(factoryDefinitions.id, factoryId),
57
+ eq(factoryDefinitions.orgId, orgId),
58
+ ),
59
+ )
60
+ .limit(1)
61
+ )[0];
62
+ if (!definition) {
63
+ throw new Error("Factory has no saved definition to restore.");
64
+ }
65
+
66
+ const version = (
67
+ await tx
68
+ .select()
69
+ .from(factoryGraphVersions)
70
+ .where(
71
+ and(
72
+ eq(factoryGraphVersions.id, versionId),
73
+ eq(factoryGraphVersions.factoryId, factoryId),
74
+ eq(factoryGraphVersions.orgId, orgId),
75
+ ),
76
+ )
77
+ .limit(1)
78
+ )[0];
79
+ if (!version) {
80
+ throw new Error("Factory graph version not found.");
81
+ }
82
+
83
+ const selectedGraph = parseFactoryGraph(version.graphJson);
84
+
85
+ if (version.version === definition.graphVersion) {
86
+ return {
87
+ ok: true,
88
+ alreadyCurrent: true,
89
+ factoryId,
90
+ versionId: version.id,
91
+ restoredFromVersion: version.version,
92
+ graphVersion: definition.graphVersion,
93
+ name: definition.name,
94
+ graph: selectedGraph,
95
+ source: "restore" as const,
96
+ };
97
+ }
98
+
99
+ const nextVersion = definition.graphVersion + 1;
100
+ const restoredGraph = normalizeFactoryGraph({
101
+ ...selectedGraph,
102
+ version: nextVersion,
103
+ });
104
+ const now = new Date().toISOString();
105
+ const nextVersionId = stableId(
106
+ "factory-graph",
107
+ orgId,
108
+ factoryId,
109
+ String(nextVersion),
110
+ );
111
+ const changeSummary = `Restored version ${version.version}.`;
112
+
113
+ const updated = await tx
114
+ .update(factoryDefinitions)
115
+ .set({
116
+ name: restoredGraph.name,
117
+ description: restoredGraph.description,
118
+ graphVersion: nextVersion,
119
+ graphJson: JSON.stringify(restoredGraph),
120
+ updatedAt: now,
121
+ ownerEmail: userEmail,
122
+ })
123
+ .where(
124
+ and(
125
+ eq(factoryDefinitions.id, factoryId),
126
+ eq(factoryDefinitions.orgId, orgId),
127
+ eq(factoryDefinitions.graphVersion, definition.graphVersion),
128
+ ),
129
+ )
130
+ .returning({ id: factoryDefinitions.id });
131
+ if (updated.length === 0) {
132
+ throw new Error(
133
+ "Factory changed while restoring. Refresh history and try again.",
134
+ );
135
+ }
136
+
137
+ await tx.insert(factoryGraphVersions).values({
138
+ id: nextVersionId,
139
+ factoryId,
140
+ version: nextVersion,
141
+ graphJson: JSON.stringify(restoredGraph),
142
+ source: "restore",
143
+ changeSummary,
144
+ createdAt: now,
145
+ createdBy: userEmail,
146
+ ownerEmail: userEmail,
147
+ orgId,
148
+ });
149
+
150
+ return {
151
+ ok: true,
152
+ alreadyCurrent: false,
153
+ factoryId,
154
+ versionId: nextVersionId,
155
+ restoredFromVersion: version.version,
156
+ graphVersion: nextVersion,
157
+ name: restoredGraph.name,
158
+ graph: restoredGraph,
159
+ source: "restore" as const,
160
+ };
161
+ });
162
+ },
163
+ });
@@ -12,10 +12,7 @@ import {
12
12
  factoryGraphSchema,
13
13
  normalizeFactoryGraph,
14
14
  } from "../server/factory-graph/contracts.js";
15
- import {
16
- DEFAULT_FACTORY_ID,
17
- readFactoryDefinition,
18
- } from "../server/factory-graph/store.js";
15
+ import { DEFAULT_FACTORY_ID } from "../server/factory-graph/store.js";
19
16
  import {
20
17
  requireWorkspaceMember,
21
18
  workspaceMemberIdentityFromContext,
@@ -24,7 +21,7 @@ import { stableId } from "../server/triage/ids.js";
24
21
 
25
22
  export default defineAction({
26
23
  description:
27
- "Create or update a Factory's versioned visual graph. Use source=ai for an agent-proposed graph and source=manual for a direct editor save. This changes configuration only; it never starts provider work.",
24
+ "Create or update a Factory's versioned visual graph. Pass expectedGraphVersion from the graph you inspected so stale edits are rejected. Use source=ai for an agent-proposed graph and source=manual for a direct editor save. This changes configuration only; it never starts provider work.",
28
25
  schema: z.object({
29
26
  factoryId: z
30
27
  .string()
@@ -38,6 +35,7 @@ export default defineAction({
38
35
  prompt: z.string().trim().max(10_000).default(""),
39
36
  source: z.enum(["manual", "ai", "seed"]).default("manual"),
40
37
  changeSummary: z.string().trim().max(500).default(""),
38
+ expectedGraphVersion: z.coerce.number().int().nonnegative(),
41
39
  graph: factoryGraphSchema,
42
40
  }),
43
41
  link: ({ result }) => ({
@@ -49,81 +47,116 @@ export default defineAction({
49
47
  label: `Open ${result.name} in Factory`,
50
48
  }),
51
49
  run: async (
52
- { factoryId, name, description, prompt, source, changeSummary, graph },
50
+ {
51
+ factoryId,
52
+ name,
53
+ description,
54
+ prompt,
55
+ source,
56
+ changeSummary,
57
+ expectedGraphVersion,
58
+ graph,
59
+ },
53
60
  context,
54
61
  ) => {
55
62
  const { userEmail, orgId } = await requireWorkspaceMember(
56
63
  workspaceMemberIdentityFromContext(context),
57
64
  );
58
65
  const db = getDb();
59
- const existing = await readFactoryDefinition(orgId, factoryId);
60
- const nextVersion = (existing?.graphVersion ?? 0) + 1;
61
- const normalizedGraph = normalizeFactoryGraph({
62
- ...graph,
63
- version: nextVersion,
64
- name,
65
- description,
66
- });
67
- const now = new Date().toISOString();
68
- const versionId = stableId(
69
- "factory-graph",
70
- orgId,
71
- factoryId,
72
- String(nextVersion),
73
- );
74
66
 
75
- await db.insert(factoryGraphVersions).values({
76
- id: versionId,
77
- factoryId,
78
- version: nextVersion,
79
- graphJson: JSON.stringify(normalizedGraph),
80
- source,
81
- changeSummary,
82
- createdAt: now,
83
- createdBy: userEmail,
84
- ownerEmail: userEmail,
85
- orgId,
86
- });
67
+ return db.transaction(async (tx) => {
68
+ const existing = (
69
+ await tx
70
+ .select()
71
+ .from(factoryDefinitions)
72
+ .where(
73
+ and(
74
+ eq(factoryDefinitions.id, factoryId),
75
+ eq(factoryDefinitions.orgId, orgId),
76
+ ),
77
+ )
78
+ .limit(1)
79
+ )[0];
80
+ if ((existing?.graphVersion ?? 0) !== expectedGraphVersion) {
81
+ throw new Error(
82
+ "Factory changed while saving. Refresh the Factory and try again.",
83
+ );
84
+ }
85
+ const nextVersion = (existing?.graphVersion ?? 0) + 1;
86
+ const normalizedGraph = normalizeFactoryGraph({
87
+ ...graph,
88
+ version: nextVersion,
89
+ name,
90
+ description,
91
+ });
92
+ const now = new Date().toISOString();
93
+ const versionId = stableId(
94
+ "factory-graph",
95
+ orgId,
96
+ factoryId,
97
+ String(nextVersion),
98
+ );
87
99
 
88
- if (existing) {
89
- await db
90
- .update(factoryDefinitions)
91
- .set({
100
+ if (existing) {
101
+ const updated = await tx
102
+ .update(factoryDefinitions)
103
+ .set({
104
+ name,
105
+ description,
106
+ prompt,
107
+ graphVersion: nextVersion,
108
+ graphJson: JSON.stringify(normalizedGraph),
109
+ updatedAt: now,
110
+ ownerEmail: userEmail,
111
+ })
112
+ .where(
113
+ and(
114
+ eq(factoryDefinitions.id, factoryId),
115
+ eq(factoryDefinitions.orgId, orgId),
116
+ eq(factoryDefinitions.graphVersion, expectedGraphVersion),
117
+ ),
118
+ )
119
+ .returning({ id: factoryDefinitions.id });
120
+ if (updated.length === 0) {
121
+ throw new Error(
122
+ "Factory changed while saving. Refresh the Factory and try again.",
123
+ );
124
+ }
125
+ } else {
126
+ await tx.insert(factoryDefinitions).values({
127
+ id: factoryId,
92
128
  name,
93
129
  description,
94
130
  prompt,
95
131
  graphVersion: nextVersion,
96
132
  graphJson: JSON.stringify(normalizedGraph),
133
+ createdAt: now,
97
134
  updatedAt: now,
98
135
  ownerEmail: userEmail,
99
- })
100
- .where(
101
- and(
102
- eq(factoryDefinitions.id, factoryId),
103
- eq(factoryDefinitions.orgId, orgId),
104
- ),
105
- );
106
- } else {
107
- await db.insert(factoryDefinitions).values({
108
- id: factoryId,
109
- name,
110
- description,
111
- prompt,
112
- graphVersion: nextVersion,
136
+ orgId,
137
+ });
138
+ }
139
+
140
+ await tx.insert(factoryGraphVersions).values({
141
+ id: versionId,
142
+ factoryId,
143
+ version: nextVersion,
113
144
  graphJson: JSON.stringify(normalizedGraph),
145
+ source,
146
+ changeSummary,
114
147
  createdAt: now,
115
- updatedAt: now,
148
+ createdBy: userEmail,
116
149
  ownerEmail: userEmail,
117
150
  orgId,
118
151
  });
119
- }
120
152
 
121
- return {
122
- ok: true,
123
- factoryId,
124
- name,
125
- graphVersion: nextVersion,
126
- source,
127
- };
153
+ return {
154
+ ok: true,
155
+ factoryId,
156
+ name,
157
+ graphVersion: nextVersion,
158
+ source,
159
+ };
160
+ });
128
161
  },
129
162
  });