@agent-native/core 0.24.1 → 0.24.3

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 (68) hide show
  1. package/README.md +22 -2
  2. package/dist/agent/thread-data-builder.d.ts +1 -0
  3. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  4. package/dist/agent/thread-data-builder.js +8 -2
  5. package/dist/agent/thread-data-builder.js.map +1 -1
  6. package/dist/chat-threads/store.d.ts +13 -0
  7. package/dist/chat-threads/store.d.ts.map +1 -1
  8. package/dist/chat-threads/store.js +87 -8
  9. package/dist/chat-threads/store.js.map +1 -1
  10. package/dist/cli/migrate.d.ts +1 -0
  11. package/dist/cli/migrate.d.ts.map +1 -1
  12. package/dist/cli/migrate.js +137 -5
  13. package/dist/cli/migrate.js.map +1 -1
  14. package/dist/cli/templates-meta.js +1 -1
  15. package/dist/cli/templates-meta.js.map +1 -1
  16. package/dist/client/AgentPanel.d.ts +2 -0
  17. package/dist/client/AgentPanel.d.ts.map +1 -1
  18. package/dist/client/AgentPanel.js +2 -2
  19. package/dist/client/AgentPanel.js.map +1 -1
  20. package/dist/client/MultiTabAssistantChat.d.ts +3 -1
  21. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  22. package/dist/client/MultiTabAssistantChat.js +12 -3
  23. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  24. package/dist/client/NewWorkspaceAppFlow.js +2 -2
  25. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  26. package/dist/client/onboarding/OnboardingPanel.js +1 -1
  27. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  28. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  29. package/dist/client/org/OrgSwitcher.js +29 -2
  30. package/dist/client/org/OrgSwitcher.js.map +1 -1
  31. package/dist/client/org/workspace-app-links.d.ts +1 -0
  32. package/dist/client/org/workspace-app-links.d.ts.map +1 -1
  33. package/dist/client/org/workspace-app-links.js +7 -1
  34. package/dist/client/org/workspace-app-links.js.map +1 -1
  35. package/dist/client/use-chat-threads.d.ts +9 -0
  36. package/dist/client/use-chat-threads.d.ts.map +1 -1
  37. package/dist/client/use-chat-threads.js +216 -32
  38. package/dist/client/use-chat-threads.js.map +1 -1
  39. package/dist/client/use-chat-threads.spec.js +368 -0
  40. package/dist/client/use-chat-threads.spec.js.map +1 -1
  41. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  42. package/dist/scripts/chat/search-chats.js +7 -1
  43. package/dist/scripts/chat/search-chats.js.map +1 -1
  44. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  45. package/dist/server/agent-chat-plugin.js +141 -6
  46. package/dist/server/agent-chat-plugin.js.map +1 -1
  47. package/dist/server/framework-request-handler.d.ts.map +1 -1
  48. package/dist/server/framework-request-handler.js +45 -0
  49. package/dist/server/framework-request-handler.js.map +1 -1
  50. package/dist/server/index.d.ts +1 -1
  51. package/dist/server/index.d.ts.map +1 -1
  52. package/dist/server/index.js +1 -1
  53. package/dist/server/index.js.map +1 -1
  54. package/dist/templates/workspace-root/AGENTS.md +6 -5
  55. package/dist/templates/workspace-root/README.md +1 -1
  56. package/docs/content/cloneable-saas.md +1 -0
  57. package/docs/content/dispatch.md +2 -2
  58. package/docs/content/faq.md +11 -10
  59. package/docs/content/getting-started.md +1 -0
  60. package/docs/content/multi-tenancy.md +1 -1
  61. package/docs/content/template-assets.md +23 -1
  62. package/docs/content/template-brain.md +31 -8
  63. package/docs/content/template-clips.md +19 -0
  64. package/docs/content/template-design.md +21 -0
  65. package/docs/content/template-forms.md +19 -0
  66. package/package.json +1 -1
  67. package/src/templates/workspace-root/AGENTS.md +6 -5
  68. package/src/templates/workspace-root/README.md +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"search-chats.js","sourceRoot":"","sources":["../../../src/scripts/chat/search-chats.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: search-chats\n *\n * Search or list past agent chat threads.\n *\n * Usage:\n * pnpm action search-chats [--query \"search term\"] [--limit N] [--format json]\n */\n\nimport { parseArgs, fail } from \"../utils.js\";\nimport { searchThreads, listThreads } from \"../../chat-threads/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\n\nfunction getOwnerEmail(): string {\n const email = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;\n if (!email) {\n fail(\n \"search-chats requires an authenticated user (request context or AGENT_USER_EMAIL env var).\",\n );\n }\n return email;\n}\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts);\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffDays = Math.floor(diffMs / 86400000);\n if (diffDays === 0)\n return d.toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n if (diffDays === 1) return \"Yesterday\";\n if (diffDays < 7) return d.toLocaleDateString([], { weekday: \"short\" });\n return d.toLocaleDateString([], { month: \"short\", day: \"numeric\" });\n}\n\nexport default async function searchChats(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action search-chats [options]\n\nOptions:\n --query <text> Search chats by title, preview, or content\n --limit N Max results (default: 20)\n --format json Output as JSON\n --help Show this help message\n\nExamples:\n pnpm action search-chats --query \"email setup\"\n pnpm action search-chats --limit 5\n pnpm action search-chats --format json`);\n return;\n }\n\n const owner = getOwnerEmail();\n const limit = parsed.limit ? parseInt(parsed.limit, 10) : 20;\n if (isNaN(limit) || limit < 1) fail(\"--limit must be a positive integer\");\n\n const query = parsed.query;\n const threads = query\n ? await searchThreads(owner, query, limit)\n : await listThreads(owner, limit, 0);\n\n if (parsed.format === \"json\") {\n console.log(\n JSON.stringify(\n {\n query: query ?? null,\n threads: threads.map((t) => ({\n id: t.id,\n title: t.title,\n preview: t.preview,\n messageCount: t.messageCount,\n updatedAt: t.updatedAt,\n })),\n count: threads.length,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n if (threads.length === 0) {\n console.log(query ? `No chats matching \"${query}\"` : \"No chat history\");\n return;\n }\n\n console.log(\n query\n ? `Chats matching \"${query}\" (${threads.length}):`\n : `Recent chats (${threads.length}):`,\n );\n console.log();\n\n for (const t of threads) {\n const title = t.title || t.preview || \"(untitled)\";\n const msgs = t.messageCount === 1 ? \"1 msg\" : `${t.messageCount} msgs`;\n const time = formatTime(t.updatedAt);\n console.log(` ${title}`);\n console.log(` ID: ${t.id} | ${msgs} | ${time}`);\n if (t.preview && t.title && t.preview !== t.title) {\n console.log(\n ` ${t.preview.slice(0, 80)}${t.preview.length > 80 ? \"...\" : \"\"}`,\n );\n }\n console.log();\n }\n}\n"]}
1
+ {"version":3,"file":"search-chats.js","sourceRoot":"","sources":["../../../src/scripts/chat/search-chats.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: search-chats\n *\n * Search or list past agent chat threads.\n *\n * Usage:\n * pnpm action search-chats [--query \"search term\"] [--limit N] [--format json]\n */\n\nimport { parseArgs, fail } from \"../utils.js\";\nimport { searchThreads, listThreads } from \"../../chat-threads/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\n\nfunction getOwnerEmail(): string {\n const email = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;\n if (!email) {\n fail(\n \"search-chats requires an authenticated user (request context or AGENT_USER_EMAIL env var).\",\n );\n }\n return email;\n}\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts);\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffDays = Math.floor(diffMs / 86400000);\n if (diffDays === 0)\n return d.toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n if (diffDays === 1) return \"Yesterday\";\n if (diffDays < 7) return d.toLocaleDateString([], { weekday: \"short\" });\n return d.toLocaleDateString([], { month: \"short\", day: \"numeric\" });\n}\n\nexport default async function searchChats(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action search-chats [options]\n\nOptions:\n --query <text> Search chats by title, preview, or content\n --limit N Max results (default: 20)\n --format json Output as JSON\n --help Show this help message\n\nExamples:\n pnpm action search-chats --query \"email setup\"\n pnpm action search-chats --limit 5\n pnpm action search-chats --format json`);\n return;\n }\n\n const owner = getOwnerEmail();\n const limit = parsed.limit ? parseInt(parsed.limit, 10) : 20;\n if (isNaN(limit) || limit < 1) fail(\"--limit must be a positive integer\");\n\n const query = parsed.query;\n const threads = query\n ? await searchThreads(owner, query, limit)\n : await listThreads(owner, limit, 0);\n\n if (parsed.format === \"json\") {\n console.log(\n JSON.stringify(\n {\n query: query ?? null,\n threads: threads.map((t) => ({\n id: t.id,\n title: t.title,\n preview: t.preview,\n messageCount: t.messageCount,\n updatedAt: t.updatedAt,\n pinnedAt: t.pinnedAt ?? null,\n archivedAt: t.archivedAt ?? null,\n })),\n count: threads.length,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n if (threads.length === 0) {\n console.log(query ? `No chats matching \"${query}\"` : \"No chat history\");\n return;\n }\n\n console.log(\n query\n ? `Chats matching \"${query}\" (${threads.length}):`\n : `Recent chats (${threads.length}):`,\n );\n console.log();\n\n for (const t of threads) {\n const title = t.title || t.preview || \"(untitled)\";\n const msgs = t.messageCount === 1 ? \"1 msg\" : `${t.messageCount} msgs`;\n const time = formatTime(t.updatedAt);\n const flags = [\n t.pinnedAt ? \"pinned\" : null,\n t.archivedAt ? \"archived\" : null,\n ].filter(Boolean);\n console.log(` ${title}`);\n console.log(\n ` ID: ${t.id} | ${msgs} | ${time}${flags.length ? ` | ${flags.join(\", \")}` : \"\"}`,\n );\n if (t.preview && t.title && t.preview !== t.title) {\n console.log(\n ` ${t.preview.slice(0, 80)}${t.preview.length > 80 ? \"...\" : \"\"}`,\n );\n }\n console.log();\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-chat-plugin.d.ts","sourceRoot":"","sources":["../../src/server/agent-chat-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-chat-plugin.d.ts","sourceRoot":"","sources":["../../src/server/agent-chat-plugin.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@ import { buildAssistantMessage, buildUserMessage, extractThreadMeta, mergeThread
14
14
  import { createError, defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, } from "h3";
15
15
  import { getSession } from "./auth.js";
16
16
  import { getOrigin } from "./google-oauth.js";
17
- import { createThread, forkThread, getThread, listThreads, searchThreads, setThreadScope, updateThreadData, withThreadDataLock, deleteThread, setThreadQueuedMessages, } from "../chat-threads/store.js";
17
+ import { createThread, forkThread, getThread, listThreads, searchThreads, renameThread, setThreadArchived, setThreadPinned, setThreadScope, updateThreadData, withThreadDataLock, deleteThread, setThreadQueuedMessages, } from "../chat-threads/store.js";
18
18
  import { resourceList, resourceListAccessible, resourceGet, resourceGetByPath, ensurePersonalDefaults, SHARED_OWNER, WORKSPACE_OWNER, } from "../resources/store.js";
19
19
  import { getFrontmatterValue, getSkillNameFromPath, parseFrontmatter, } from "../resources/metadata.js";
20
20
  import nodePath from "node:path";
@@ -880,7 +880,8 @@ async function createResourceScriptEntries() {
880
880
  }
881
881
  }
882
882
  /**
883
- * Creates a unified chat-history ActionEntry that dispatches to search or open.
883
+ * Creates a unified chat-history ActionEntry that dispatches to search, open,
884
+ * rename, or lightweight organization actions.
884
885
  */
885
886
  async function createChatScriptEntries() {
886
887
  try {
@@ -925,14 +926,14 @@ async function createChatScriptEntries() {
925
926
  return {
926
927
  "chat-history": {
927
928
  tool: {
928
- description: "Manage past agent chat threads. Use action 'search' to find previous conversations by keyword, or 'open' to open a thread in the UI.",
929
+ description: "Manage past agent chat threads. Use action 'search' to find previous conversations by keyword, 'open' to open a thread in the UI, or 'rename'/'pin'/'unpin'/'archive' to organize history.",
929
930
  parameters: {
930
931
  type: "object",
931
932
  properties: {
932
933
  action: {
933
934
  type: "string",
934
935
  description: "The operation to perform",
935
- enum: ["search", "open"],
936
+ enum: ["search", "open", "rename", "pin", "unpin", "archive"],
936
937
  },
937
938
  query: {
938
939
  type: "string",
@@ -949,7 +950,11 @@ async function createChatScriptEntries() {
949
950
  },
950
951
  id: {
951
952
  type: "string",
952
- description: "(open) The chat thread ID to open",
953
+ description: "(open, rename, pin, unpin, archive) The chat thread ID to manage",
954
+ },
955
+ title: {
956
+ type: "string",
957
+ description: "(rename) New chat title",
953
958
  },
954
959
  },
955
960
  required: ["action"],
@@ -959,6 +964,49 @@ async function createChatScriptEntries() {
959
964
  if (args?.action === "open") {
960
965
  return openEntry.run(args);
961
966
  }
967
+ if (args?.action === "rename" ||
968
+ args?.action === "pin" ||
969
+ args?.action === "unpin" ||
970
+ args?.action === "archive") {
971
+ const id = typeof args?.id === "string" ? args.id : "";
972
+ if (!id)
973
+ return "Missing required id.";
974
+ const owner = getRequestRunContext()?.owner ?? getRequestUserEmail() ?? "";
975
+ if (!owner)
976
+ return "No authenticated user is available.";
977
+ const thread = await getThread(id);
978
+ if (!thread || thread.ownerEmail !== owner) {
979
+ return `Chat thread "${id}" not found.`;
980
+ }
981
+ const title = thread.title || thread.preview || "(untitled)";
982
+ if (args.action === "rename") {
983
+ const nextTitle = typeof args?.title === "string"
984
+ ? args.title.replace(/\s+/g, " ").trim().slice(0, 160)
985
+ : "";
986
+ if (!nextTitle)
987
+ return "Missing required title.";
988
+ const renamed = await renameThread(id, nextTitle, {
989
+ ownerEmail: owner,
990
+ });
991
+ if (!renamed)
992
+ return `Chat thread "${id}" could not be renamed.`;
993
+ return `Renamed chat "${title}" to "${nextTitle}".`;
994
+ }
995
+ if (args.action === "archive") {
996
+ const archived = await setThreadArchived(id, true, {
997
+ ownerEmail: owner,
998
+ });
999
+ if (!archived)
1000
+ return `Chat thread "${id}" could not be archived.`;
1001
+ return `Archived chat: ${title}`;
1002
+ }
1003
+ const pinned = await setThreadPinned(id, args.action === "pin", {
1004
+ ownerEmail: owner,
1005
+ });
1006
+ if (!pinned)
1007
+ return `Chat thread "${id}" could not be updated.`;
1008
+ return `${args.action === "pin" ? "Pinned" : "Unpinned"} chat: ${title}`;
1009
+ }
962
1010
  return searchEntry.run(args);
963
1011
  },
964
1012
  },
@@ -1488,6 +1536,7 @@ Use for charts, visualizations, previews. Don't use for simple text/tables or ex
1488
1536
  You can search and restore previous chat conversations using \`chat-history\`:
1489
1537
  - \`chat-history\` (action: "search") — Search or list past chat threads by keyword
1490
1538
  - \`chat-history\` (action: "open") — Open a chat thread in the UI as a new tab and focus it
1539
+ - \`chat-history\` (actions: "rename", "pin", "unpin", "archive") — Organize a known chat thread by ID
1491
1540
 
1492
1541
  When the user asks to find a previous conversation, use \`chat-history\` with action "search" first to find matching threads, then action "open" to restore the one they want.`,
1493
1542
  "agent-teams": `### Agent Teams — Orchestration
@@ -1680,6 +1729,7 @@ Which routes are renderable as embeds is template-specific — the app's \`AGENT
1680
1729
  You can search and restore previous chat conversations using \`chat-history\`:
1681
1730
  - \`chat-history\` (action: "search") — Search or list past chat threads by keyword
1682
1731
  - \`chat-history\` (action: "open") — Open a chat thread in the UI as a new tab and focus it
1732
+ - \`chat-history\` (actions: "rename", "pin", "unpin", "archive") — Organize a known chat thread by ID
1683
1733
 
1684
1734
  When the user asks to find a previous conversation, use \`chat-history\` with action "search" first to find matching threads, then action "open" to restore the one they want.
1685
1735
 
@@ -4766,6 +4816,21 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4766
4816
  const body = await readBody(event);
4767
4817
  let newThreadData = body.threadData || thread.threadData;
4768
4818
  let newMessageCount = body.messageCount ?? thread.messageCount;
4819
+ let nextTitle = typeof body.title === "string" ? body.title : thread.title;
4820
+ const nextPreview = typeof body.preview === "string"
4821
+ ? body.preview
4822
+ : thread.preview;
4823
+ const preserveTitleOverride = (repo) => {
4824
+ if (repo &&
4825
+ typeof repo === "object" &&
4826
+ typeof repo
4827
+ ._titleOverride === "string" &&
4828
+ repo._titleOverride.trim()) {
4829
+ const meta = extractThreadMeta(repo);
4830
+ if (meta.title)
4831
+ nextTitle = meta.title;
4832
+ }
4833
+ };
4769
4834
  // Merge the incoming full-thread blob over the current SQL
4770
4835
  // copy. Periodic saves can be stale relative to server-side
4771
4836
  // run completion, and threadRuntime.export() does not carry
@@ -4779,12 +4844,21 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4779
4844
  if (Array.isArray(merged.messages)) {
4780
4845
  newMessageCount = merged.messages.length;
4781
4846
  }
4847
+ preserveTitleOverride(merged);
4782
4848
  }
4783
4849
  catch {
4784
4850
  // Invalid JSON in either side — fall back to raw body blob.
4785
4851
  }
4786
4852
  }
4787
- await updateThreadData(threadId, newThreadData, body.title ?? thread.title, body.preview ?? thread.preview, newMessageCount);
4853
+ else {
4854
+ try {
4855
+ preserveTitleOverride(JSON.parse(newThreadData));
4856
+ }
4857
+ catch {
4858
+ // Invalid JSON — keep the title supplied by the client.
4859
+ }
4860
+ }
4861
+ await updateThreadData(threadId, newThreadData, nextTitle, nextPreview, newMessageCount);
4788
4862
  // Scope updates piggyback on the PUT — the client uses this
4789
4863
  // path for both "detach" (scope: null) and "retag" flows.
4790
4864
  // Send the field as `scope: undefined` (or omit it) when
@@ -4813,6 +4887,67 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4813
4887
  await setThreadQueuedMessages(threadId, queued);
4814
4888
  return { ok: true };
4815
4889
  }
4890
+ if (method === "POST" && isThreadSubroute("rename")) {
4891
+ const thread = await getThread(threadId);
4892
+ if (!thread || thread.ownerEmail !== owner) {
4893
+ setResponseStatus(event, 404);
4894
+ return { error: "Thread not found" };
4895
+ }
4896
+ const body = await readBody(event).catch(() => ({}));
4897
+ const title = typeof body?.title === "string"
4898
+ ? body.title.replace(/\s+/g, " ").trim().slice(0, 160)
4899
+ : "";
4900
+ if (!title) {
4901
+ setResponseStatus(event, 400);
4902
+ return { error: "Title is required" };
4903
+ }
4904
+ const renamed = await renameThread(threadId, title, {
4905
+ ownerEmail: owner,
4906
+ });
4907
+ if (!renamed) {
4908
+ setResponseStatus(event, 404);
4909
+ return { error: "Thread not found" };
4910
+ }
4911
+ return { ok: true };
4912
+ }
4913
+ if (method === "POST" && isThreadSubroute("pin")) {
4914
+ const thread = await getThread(threadId);
4915
+ if (!thread || thread.ownerEmail !== owner) {
4916
+ setResponseStatus(event, 404);
4917
+ return { error: "Thread not found" };
4918
+ }
4919
+ const body = await readBody(event).catch(() => ({}));
4920
+ if (typeof body?.pinned !== "boolean") {
4921
+ setResponseStatus(event, 400);
4922
+ return { error: "pinned boolean is required" };
4923
+ }
4924
+ const pinned = await setThreadPinned(threadId, body.pinned, {
4925
+ ownerEmail: owner,
4926
+ });
4927
+ if (!pinned) {
4928
+ setResponseStatus(event, 404);
4929
+ return { error: "Thread not found" };
4930
+ }
4931
+ return { ok: true };
4932
+ }
4933
+ if (method === "POST" && isThreadSubroute("archive")) {
4934
+ const thread = await getThread(threadId);
4935
+ if (!thread || thread.ownerEmail !== owner) {
4936
+ setResponseStatus(event, 404);
4937
+ return { error: "Thread not found" };
4938
+ }
4939
+ const body = await readBody(event).catch(() => ({}));
4940
+ if (typeof body?.archived !== "boolean") {
4941
+ setResponseStatus(event, 400);
4942
+ return { error: "archived boolean is required" };
4943
+ }
4944
+ const archived = await setThreadArchived(threadId, body.archived, { ownerEmail: owner });
4945
+ if (!archived) {
4946
+ setResponseStatus(event, 404);
4947
+ return { error: "Thread not found" };
4948
+ }
4949
+ return { ok: true };
4950
+ }
4816
4951
  // POST /threads/:id/fork — duplicate a thread with all its messages
4817
4952
  if (method === "POST" && isThreadSubroute("fork")) {
4818
4953
  const body = await readBody(event);