@agent-native/core 0.84.22 → 0.84.23
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/core/CHANGELOG.md +8 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/model-config.ts +1 -1
- package/corpus/core/src/cli/skills.ts +17 -3
- package/corpus/core/src/notifications/index.ts +1 -0
- package/corpus/core/src/notifications/registry.ts +13 -1
- package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +18 -1
- package/corpus/templates/analytics/server/db/schema.ts +1 -1
- package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +4 -1
- package/corpus/templates/analytics/server/lib/analytics-alerts.ts +76 -7
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +30 -1
- package/corpus/templates/clips/actions/finalize-recording.ts +84 -4
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +256 -0
- package/corpus/templates/clips/actions/reprocess-recording.ts +160 -0
- package/corpus/templates/clips/changelog/2026-07-01-shared-clips-now-start-playing-and-scrub-instantly-instead-o.md +6 -0
- package/corpus/templates/clips/server/lib/video-remux.ts +222 -0
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +75 -19
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +11 -1
- package/corpus/templates/design/changelog/2026-07-01-design-chat-no-longer-shows-an-empty-state-selection-chip-in-the-composer.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/videos/.agents/skills/frontend-design/SKILL.md +2 -0
- package/dist/agent/model-config.js +1 -1
- package/dist/agent/model-config.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +17 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +1 -1
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/registry.d.ts +5 -0
- package/dist/notifications/registry.d.ts.map +1 -1
- package/dist/notifications/registry.js +4 -1
- package/dist/notifications/registry.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +5 -5
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
- package/package.json +1 -1
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
|
@@ -49,11 +49,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
49
49
|
error: string;
|
|
50
50
|
states?: undefined;
|
|
51
51
|
} | {
|
|
52
|
-
error?: undefined;
|
|
53
52
|
states: {
|
|
54
53
|
clientId: number;
|
|
55
54
|
state: string;
|
|
56
55
|
}[];
|
|
56
|
+
error?: undefined;
|
|
57
57
|
}>>;
|
|
58
58
|
/**
|
|
59
59
|
* GET /_agent-native/collab/:docId/users
|
|
@@ -64,10 +64,10 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
|
|
|
64
64
|
error: string;
|
|
65
65
|
users?: undefined;
|
|
66
66
|
} | {
|
|
67
|
-
error?: undefined;
|
|
68
67
|
users: {
|
|
69
68
|
clientId: number;
|
|
70
69
|
lastSeen: number;
|
|
71
70
|
}[];
|
|
71
|
+
error?: undefined;
|
|
72
72
|
}>>;
|
|
73
73
|
//# sourceMappingURL=awareness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAUN;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAUD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAUN;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAUD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;kBAuCa,MAAM;eAAS,MAAM;;;GAa1D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;kBAWM,MAAM;kBAAY,MAAM;;;GAMvD,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export type { Notification, NotificationSeverity, NotificationInput, NotificationMeta, NotificationChannel, } from "./types.js";
|
|
2
|
-
export { notify, registerNotificationChannel, unregisterNotificationChannel, listNotificationChannels, listNotifications, countUnread, markNotificationRead, markAllNotificationsRead, deleteNotification, } from "./registry.js";
|
|
2
|
+
export { notify, notifyWithDelivery, registerNotificationChannel, unregisterNotificationChannel, listNotificationChannels, listNotifications, countUnread, markNotificationRead, markAllNotificationsRead, deleteNotification, } from "./registry.js";
|
|
3
3
|
export { registerBuiltinNotificationChannels } from "./channels.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,MAAM,EACN,2BAA2B,EAC3B,6BAA6B,EAC7B,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mCAAmC,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,2BAA2B,EAC3B,6BAA6B,EAC7B,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mCAAmC,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { notify, registerNotificationChannel, unregisterNotificationChannel, listNotificationChannels, listNotifications, countUnread, markNotificationRead, markAllNotificationsRead, deleteNotification, } from "./registry.js";
|
|
1
|
+
export { notify, notifyWithDelivery, registerNotificationChannel, unregisterNotificationChannel, listNotificationChannels, listNotifications, countUnread, markNotificationRead, markAllNotificationsRead, deleteNotification, } from "./registry.js";
|
|
2
2
|
export { registerBuiltinNotificationChannels } from "./channels.js";
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,MAAM,EACN,2BAA2B,EAC3B,6BAA6B,EAC7B,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mCAAmC,EAAE,MAAM,eAAe,CAAC","sourcesContent":["export type {\n Notification,\n NotificationSeverity,\n NotificationInput,\n NotificationMeta,\n NotificationChannel,\n} from \"./types.js\";\n\nexport {\n notify,\n registerNotificationChannel,\n unregisterNotificationChannel,\n listNotificationChannels,\n listNotifications,\n countUnread,\n markNotificationRead,\n markAllNotificationsRead,\n deleteNotification,\n} from \"./registry.js\";\n\nexport { registerBuiltinNotificationChannels } from \"./channels.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,2BAA2B,EAC3B,6BAA6B,EAC7B,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mCAAmC,EAAE,MAAM,eAAe,CAAC","sourcesContent":["export type {\n Notification,\n NotificationSeverity,\n NotificationInput,\n NotificationMeta,\n NotificationChannel,\n} from \"./types.js\";\n\nexport {\n notify,\n notifyWithDelivery,\n registerNotificationChannel,\n unregisterNotificationChannel,\n listNotificationChannels,\n listNotifications,\n countUnread,\n markNotificationRead,\n markAllNotificationsRead,\n deleteNotification,\n} from \"./registry.js\";\n\nexport { registerBuiltinNotificationChannels } from \"./channels.js\";\n"]}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { type NotificationChannel, type NotificationInput, type NotificationMeta, type Notification } from "./types.js";
|
|
2
|
+
export interface NotificationDeliveryResult {
|
|
3
|
+
notification?: Notification;
|
|
4
|
+
deliveredChannels: string[];
|
|
5
|
+
}
|
|
2
6
|
export declare function registerNotificationChannel(channel: NotificationChannel): void;
|
|
3
7
|
export declare function unregisterNotificationChannel(name: string): boolean;
|
|
4
8
|
export declare function listNotificationChannels(): string[];
|
|
5
9
|
export declare function notify(input: NotificationInput, meta: NotificationMeta): Promise<Notification | undefined>;
|
|
10
|
+
export declare function notifyWithDelivery(input: NotificationInput, meta: NotificationMeta): Promise<NotificationDeliveryResult>;
|
|
6
11
|
/** Test helper — drops all registered channels. */
|
|
7
12
|
export declare function __resetNotificationChannels(): void;
|
|
8
13
|
export { listNotifications, markNotificationRead, markAllNotificationsRead, deleteNotification, countUnread, } from "./store.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/notifications/registry.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/notifications/registry.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,0BAA0B;IACzC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAiCD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,mBAAmB,GAC3B,IAAI,CAUN;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,wBAAwB,IAAI,MAAM,EAAE,CAEnD;AAgBD,wBAAsB,MAAM,CAC1B,KAAK,EAAE,iBAAiB,EACxB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAEnC;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,iBAAiB,EACxB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,0BAA0B,CAAC,CAoFrC;AASD,mDAAmD;AACnD,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAED,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
|
@@ -58,6 +58,9 @@ export function listNotificationChannels() {
|
|
|
58
58
|
const MAX_TITLE_LEN = 100;
|
|
59
59
|
const MAX_BODY_LEN = 2000;
|
|
60
60
|
export async function notify(input, meta) {
|
|
61
|
+
return (await notifyWithDelivery(input, meta)).notification;
|
|
62
|
+
}
|
|
63
|
+
export async function notifyWithDelivery(input, meta) {
|
|
61
64
|
if (!meta?.owner) {
|
|
62
65
|
throw new Error("notify: meta.owner is required");
|
|
63
66
|
}
|
|
@@ -129,7 +132,7 @@ export async function notify(input, meta) {
|
|
|
129
132
|
// best-effort
|
|
130
133
|
}
|
|
131
134
|
}
|
|
132
|
-
return stored;
|
|
135
|
+
return { notification: stored, deliveredChannels: delivered };
|
|
133
136
|
}
|
|
134
137
|
function selectChannels(allowlist) {
|
|
135
138
|
const registry = getRegistry();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/notifications/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { emit as emitBusEvent } from \"../event-bus/bus.js\";\nimport { registerEvent } from \"../event-bus/registry.js\";\nimport type { EventDefinition } from \"../event-bus/types.js\";\nimport { truncate } from \"../shared/truncate.js\";\nimport { insertNotification, updateDeliveredChannels } from \"./store.js\";\nimport {\n NOTIFICATION_SEVERITIES,\n type NotificationChannel,\n type NotificationInput,\n type NotificationMeta,\n type Notification,\n} from \"./types.js\";\n\nregisterEvent({\n name: \"notification.sent\",\n description:\n \"Fires after notify() delivers to at least one channel. Automations can chain off this — e.g. fan critical notifications to Slack.\",\n payloadSchema: z.object({\n notificationId: z.string().optional(),\n severity: z.enum(NOTIFICATION_SEVERITIES),\n title: z.string(),\n body: z.string().optional(),\n deliveredChannels: z.array(z.string()),\n }) as unknown as EventDefinition[\"payloadSchema\"],\n example: {\n notificationId: \"ntf_abc\",\n severity: \"critical\",\n title: \"Payment failed\",\n body: \"Card ending 4242 declined\",\n deliveredChannels: [\"inbox\", \"webhook\"],\n },\n});\n\nconst REGISTRY_KEY = Symbol.for(\"@agent-native/core/notifications.registry\");\ninterface GlobalWithRegistry {\n [REGISTRY_KEY]?: Map<string, NotificationChannel>;\n}\n\nfunction getRegistry(): Map<string, NotificationChannel> {\n const g = globalThis as unknown as GlobalWithRegistry;\n if (!g[REGISTRY_KEY]) g[REGISTRY_KEY] = new Map();\n return g[REGISTRY_KEY];\n}\n\nexport function registerNotificationChannel(\n channel: NotificationChannel,\n): void {\n if (!channel?.name) {\n throw new Error(\"registerNotificationChannel: channel.name is required\");\n }\n if (typeof channel.deliver !== \"function\") {\n throw new Error(\n \"registerNotificationChannel: channel.deliver must be a function\",\n );\n }\n getRegistry().set(channel.name, channel);\n}\n\nexport function unregisterNotificationChannel(name: string): boolean {\n return getRegistry().delete(name);\n}\n\nexport function listNotificationChannels(): string[] {\n return Array.from(getRegistry().keys());\n}\n\n/**\n * Deliver a notification.\n *\n * The `inbox` channel always persists a row that drives the in-app UI\n * (bell + toast). Additional channels (webhook, custom) run in parallel,\n * best-effort. Returns the stored Notification when `inbox` ran, otherwise\n * `undefined`.\n *\n * Also emits `notification.sent` on the event bus so automations can react\n * to notifications (e.g. \"when a critical notification fires, also page me\").\n */\nconst MAX_TITLE_LEN = 100;\nconst MAX_BODY_LEN = 2000;\n\nexport async function notify(\n input: NotificationInput,\n meta: NotificationMeta,\n): Promise<Notification | undefined> {\n if (!meta?.owner) {\n throw new Error(\"notify: meta.owner is required\");\n }\n input = {\n ...input,\n title: truncate(input.title, MAX_TITLE_LEN),\n body: truncate(input.body, MAX_BODY_LEN),\n };\n const channels = selectChannels(input.channels);\n\n // The inbox channel is always included unless explicitly excluded.\n const runInbox = !input.channels || input.channels.includes(\"inbox\");\n const delivered: string[] = [];\n let stored: Notification | undefined;\n\n if (runInbox) {\n try {\n // Stored with just \"inbox\" first; the real delivered list is written\n // after fan-out so a failing webhook doesn't claim it was delivered.\n stored = await insertNotification({\n owner: meta.owner,\n severity: input.severity,\n title: input.title,\n body: input.body,\n metadata: input.metadata,\n deliveredChannels: [\"inbox\"],\n });\n delivered.push(\"inbox\");\n } catch (err) {\n console.error(\"[notifications] inbox persist failed:\", err);\n }\n }\n\n // Await every channel so a 500-ing webhook doesn't end up in `delivered`.\n const results = await Promise.allSettled(\n channels.map(async (channel) => {\n await channel.deliver(input, meta);\n return channel.name;\n }),\n );\n results.forEach((r, i) => {\n if (r.status === \"fulfilled\") {\n delivered.push(r.value);\n } else {\n console.error(\n `[notifications] channel \"${channels[i].name}\" failed:`,\n r.reason,\n );\n }\n });\n\n const hasExtraChannel = delivered.some((c) => c !== \"inbox\");\n if (stored && hasExtraChannel) {\n try {\n await updateDeliveredChannels(stored.id, delivered);\n stored = { ...stored, deliveredChannels: delivered };\n } catch (err) {\n console.error(\"[notifications] delivered-channel update failed:\", err);\n }\n }\n\n // Only emit when at least one channel delivered — an emission with an\n // empty delivery list (and likely a null notificationId) would mislead\n // any automation chaining off this event.\n if (delivered.length > 0) {\n try {\n emitBusEvent(\n \"notification.sent\",\n {\n notificationId: stored?.id,\n severity: input.severity,\n title: input.title,\n body: input.body,\n deliveredChannels: delivered,\n },\n { owner: meta.owner },\n );\n } catch {\n // best-effort\n }\n }\n\n return stored;\n}\n\nfunction selectChannels(allowlist?: string[]): NotificationChannel[] {\n const registry = getRegistry();\n const all = Array.from(registry.values());\n if (!allowlist) return all;\n return all.filter((c) => allowlist.includes(c.name));\n}\n\n/** Test helper — drops all registered channels. */\nexport function __resetNotificationChannels(): void {\n getRegistry().clear();\n}\n\nexport {\n listNotifications,\n markNotificationRead,\n markAllNotificationsRead,\n deleteNotification,\n countUnread,\n} from \"./store.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/notifications/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { emit as emitBusEvent } from \"../event-bus/bus.js\";\nimport { registerEvent } from \"../event-bus/registry.js\";\nimport type { EventDefinition } from \"../event-bus/types.js\";\nimport { truncate } from \"../shared/truncate.js\";\nimport { insertNotification, updateDeliveredChannels } from \"./store.js\";\nimport {\n NOTIFICATION_SEVERITIES,\n type NotificationChannel,\n type NotificationInput,\n type NotificationMeta,\n type Notification,\n} from \"./types.js\";\n\nexport interface NotificationDeliveryResult {\n notification?: Notification;\n deliveredChannels: string[];\n}\n\nregisterEvent({\n name: \"notification.sent\",\n description:\n \"Fires after notify() delivers to at least one channel. Automations can chain off this — e.g. fan critical notifications to Slack.\",\n payloadSchema: z.object({\n notificationId: z.string().optional(),\n severity: z.enum(NOTIFICATION_SEVERITIES),\n title: z.string(),\n body: z.string().optional(),\n deliveredChannels: z.array(z.string()),\n }) as unknown as EventDefinition[\"payloadSchema\"],\n example: {\n notificationId: \"ntf_abc\",\n severity: \"critical\",\n title: \"Payment failed\",\n body: \"Card ending 4242 declined\",\n deliveredChannels: [\"inbox\", \"webhook\"],\n },\n});\n\nconst REGISTRY_KEY = Symbol.for(\"@agent-native/core/notifications.registry\");\ninterface GlobalWithRegistry {\n [REGISTRY_KEY]?: Map<string, NotificationChannel>;\n}\n\nfunction getRegistry(): Map<string, NotificationChannel> {\n const g = globalThis as unknown as GlobalWithRegistry;\n if (!g[REGISTRY_KEY]) g[REGISTRY_KEY] = new Map();\n return g[REGISTRY_KEY];\n}\n\nexport function registerNotificationChannel(\n channel: NotificationChannel,\n): void {\n if (!channel?.name) {\n throw new Error(\"registerNotificationChannel: channel.name is required\");\n }\n if (typeof channel.deliver !== \"function\") {\n throw new Error(\n \"registerNotificationChannel: channel.deliver must be a function\",\n );\n }\n getRegistry().set(channel.name, channel);\n}\n\nexport function unregisterNotificationChannel(name: string): boolean {\n return getRegistry().delete(name);\n}\n\nexport function listNotificationChannels(): string[] {\n return Array.from(getRegistry().keys());\n}\n\n/**\n * Deliver a notification.\n *\n * The `inbox` channel always persists a row that drives the in-app UI\n * (bell + toast). Additional channels (webhook, custom) run in parallel,\n * best-effort. Returns the stored Notification when `inbox` ran, otherwise\n * `undefined`.\n *\n * Also emits `notification.sent` on the event bus so automations can react\n * to notifications (e.g. \"when a critical notification fires, also page me\").\n */\nconst MAX_TITLE_LEN = 100;\nconst MAX_BODY_LEN = 2000;\n\nexport async function notify(\n input: NotificationInput,\n meta: NotificationMeta,\n): Promise<Notification | undefined> {\n return (await notifyWithDelivery(input, meta)).notification;\n}\n\nexport async function notifyWithDelivery(\n input: NotificationInput,\n meta: NotificationMeta,\n): Promise<NotificationDeliveryResult> {\n if (!meta?.owner) {\n throw new Error(\"notify: meta.owner is required\");\n }\n input = {\n ...input,\n title: truncate(input.title, MAX_TITLE_LEN),\n body: truncate(input.body, MAX_BODY_LEN),\n };\n const channels = selectChannels(input.channels);\n\n // The inbox channel is always included unless explicitly excluded.\n const runInbox = !input.channels || input.channels.includes(\"inbox\");\n const delivered: string[] = [];\n let stored: Notification | undefined;\n\n if (runInbox) {\n try {\n // Stored with just \"inbox\" first; the real delivered list is written\n // after fan-out so a failing webhook doesn't claim it was delivered.\n stored = await insertNotification({\n owner: meta.owner,\n severity: input.severity,\n title: input.title,\n body: input.body,\n metadata: input.metadata,\n deliveredChannels: [\"inbox\"],\n });\n delivered.push(\"inbox\");\n } catch (err) {\n console.error(\"[notifications] inbox persist failed:\", err);\n }\n }\n\n // Await every channel so a 500-ing webhook doesn't end up in `delivered`.\n const results = await Promise.allSettled(\n channels.map(async (channel) => {\n await channel.deliver(input, meta);\n return channel.name;\n }),\n );\n results.forEach((r, i) => {\n if (r.status === \"fulfilled\") {\n delivered.push(r.value);\n } else {\n console.error(\n `[notifications] channel \"${channels[i].name}\" failed:`,\n r.reason,\n );\n }\n });\n\n const hasExtraChannel = delivered.some((c) => c !== \"inbox\");\n if (stored && hasExtraChannel) {\n try {\n await updateDeliveredChannels(stored.id, delivered);\n stored = { ...stored, deliveredChannels: delivered };\n } catch (err) {\n console.error(\"[notifications] delivered-channel update failed:\", err);\n }\n }\n\n // Only emit when at least one channel delivered — an emission with an\n // empty delivery list (and likely a null notificationId) would mislead\n // any automation chaining off this event.\n if (delivered.length > 0) {\n try {\n emitBusEvent(\n \"notification.sent\",\n {\n notificationId: stored?.id,\n severity: input.severity,\n title: input.title,\n body: input.body,\n deliveredChannels: delivered,\n },\n { owner: meta.owner },\n );\n } catch {\n // best-effort\n }\n }\n\n return { notification: stored, deliveredChannels: delivered };\n}\n\nfunction selectChannels(allowlist?: string[]): NotificationChannel[] {\n const registry = getRegistry();\n const all = Array.from(registry.values());\n if (!allowlist) return all;\n return all.filter((c) => allowlist.includes(c.name));\n}\n\n/** Test helper — drops all registered channels. */\nexport function __resetNotificationChannels(): void {\n getRegistry().clear();\n}\n\nexport {\n listNotifications,\n markNotificationRead,\n markAllNotificationsRead,\n deleteNotification,\n countUnread,\n} from \"./store.js\";\n"]}
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
* DELETE /_agent-native/notifications/:id — delete
|
|
12
12
|
*/
|
|
13
13
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
14
|
-
error?: undefined;
|
|
15
14
|
count: number;
|
|
16
15
|
updated?: undefined;
|
|
16
|
+
error?: undefined;
|
|
17
17
|
ok?: undefined;
|
|
18
18
|
} | {
|
|
19
|
-
error?: undefined;
|
|
20
19
|
count?: undefined;
|
|
21
20
|
updated: number;
|
|
21
|
+
error?: undefined;
|
|
22
22
|
ok?: undefined;
|
|
23
23
|
} | {
|
|
24
24
|
count?: undefined;
|
|
@@ -26,9 +26,9 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
|
|
|
26
26
|
error: string;
|
|
27
27
|
ok?: undefined;
|
|
28
28
|
} | {
|
|
29
|
-
error?: undefined;
|
|
30
29
|
count?: undefined;
|
|
31
30
|
updated?: undefined;
|
|
32
31
|
ok: boolean;
|
|
32
|
+
error?: undefined;
|
|
33
33
|
}>>;
|
|
34
34
|
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -41,28 +41,28 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
41
41
|
thumbsUpRate: number;
|
|
42
42
|
avgEvalScore: number;
|
|
43
43
|
} | {
|
|
44
|
-
error?: undefined;
|
|
45
|
-
ok?: undefined;
|
|
46
44
|
summary: import("./types.js").TraceSummary;
|
|
47
45
|
spans: import("./types.js").TraceSpan[];
|
|
48
46
|
id?: undefined;
|
|
49
|
-
} | {
|
|
50
47
|
error?: undefined;
|
|
51
48
|
ok?: undefined;
|
|
49
|
+
} | {
|
|
52
50
|
summary?: undefined;
|
|
53
51
|
spans?: undefined;
|
|
54
52
|
id: string;
|
|
55
|
-
|
|
53
|
+
error?: undefined;
|
|
56
54
|
ok?: undefined;
|
|
55
|
+
} | {
|
|
57
56
|
summary?: undefined;
|
|
58
57
|
spans?: undefined;
|
|
59
58
|
id?: undefined;
|
|
60
59
|
error: any;
|
|
60
|
+
ok?: undefined;
|
|
61
61
|
} | {
|
|
62
|
-
error?: undefined;
|
|
63
62
|
summary?: undefined;
|
|
64
63
|
spans?: undefined;
|
|
65
64
|
id?: undefined;
|
|
65
|
+
error?: undefined;
|
|
66
66
|
ok: boolean;
|
|
67
67
|
}>>;
|
|
68
68
|
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -27,11 +27,11 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
|
|
|
27
27
|
export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
28
28
|
error: any;
|
|
29
29
|
} | {
|
|
30
|
-
error?: undefined;
|
|
31
30
|
ok: boolean;
|
|
32
31
|
key: string;
|
|
33
32
|
baseUrlKey?: string;
|
|
34
33
|
scope: AgentEngineApiKeyScope;
|
|
34
|
+
error?: undefined;
|
|
35
35
|
}>>;
|
|
36
36
|
export {};
|
|
37
37
|
//# sourceMappingURL=agent-engine-api-key-route.d.ts.map
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.84.
|
|
3
|
+
"version": "0.84.23",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|