@agent-native/core 0.114.1 → 0.114.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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +30 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/cli/create.ts +23 -0
- package/corpus/core/src/cli/skills.ts +24 -0
- package/corpus/core/src/db/request-telemetry.ts +32 -8
- package/corpus/core/src/settings/store.ts +15 -6
- package/corpus/core/src/shared/optional-node-builtins.ts +66 -0
- package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/core/src/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/core/src/templates/default/AGENTS.md +4 -1
- package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/core/src/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/core/src/templates/headless/AGENTS.md +5 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +26 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/AGENTS.md +3 -1
- package/corpus/core/src/templates/workspace-root/AGENTS.md +3 -1
- package/corpus/core/src/vite/client.ts +5 -0
- package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/analytics/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/analytics/AGENTS.md +5 -0
- package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/assets/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/assets/AGENTS.md +5 -0
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -2
- package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/brain/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/brain/AGENTS.md +5 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/calendar/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/calendar/AGENTS.md +5 -0
- package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/chat/AGENTS.md +4 -1
- package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/clips/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/clips/AGENTS.md +5 -0
- package/corpus/templates/clips/shared/feature-flags.ts +1 -1
- package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/content/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/content/AGENTS.md +5 -0
- package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/design/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/design/AGENTS.md +5 -0
- package/corpus/templates/design/actions/update-file.ts +10 -1
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +30 -1
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +14 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +547 -50
- package/corpus/templates/design/app/components/design/dnd-debug.ts +27 -0
- package/corpus/templates/design/app/components/design/multi-screen/draft-primitives.ts +19 -2
- package/corpus/templates/design/app/i18n-data.ts +19 -0
- package/corpus/templates/design/app/lib/design-save-outbox.ts +46 -2
- package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +4 -9
- package/corpus/templates/design/app/pages/design-editor/history.ts +14 -1
- package/corpus/templates/design/changelog/2026-07-17-drawn-shapes-stay-free-positioned-when-dragged.md +6 -0
- package/corpus/templates/design/changelog/2026-07-17-shapes-show-a-live-outline-while-you-draw.md +6 -0
- package/corpus/templates/design/shared/drag-reflow.ts +375 -0
- package/corpus/templates/design/shared/full-app.ts +1 -1
- package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/dispatch/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/dispatch/AGENTS.md +5 -0
- package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/forms/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/forms/AGENTS.md +5 -0
- package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/macros/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/macros/AGENTS.md +5 -0
- package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/mail/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/mail/AGENTS.md +5 -0
- package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/plan/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/plan/AGENTS.md +5 -0
- package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/slides/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/slides/AGENTS.md +5 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/tasks/.agents/skills/feature-flags/SKILL.md +1 -1
- package/corpus/templates/tasks/AGENTS.md +5 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +21 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +19 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/request-telemetry.d.ts.map +1 -1
- package/dist/db/request-telemetry.js +24 -6
- package/dist/db/request-telemetry.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/settings/store.d.ts +1 -1
- package/dist/settings/store.d.ts.map +1 -1
- package/dist/settings/store.js +14 -6
- package/dist/settings/store.js.map +1 -1
- package/dist/shared/optional-node-builtins.d.ts +23 -0
- package/dist/shared/optional-node-builtins.d.ts.map +1 -0
- package/dist/shared/optional-node-builtins.js +35 -0
- package/dist/shared/optional-node-builtins.js.map +1 -0
- package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/dist/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/templates/chat/AGENTS.md +4 -1
- package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/dist/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/templates/default/AGENTS.md +4 -1
- package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/dist/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/templates/headless/AGENTS.md +5 -1
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +26 -0
- package/dist/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
- package/dist/templates/workspace-core/AGENTS.md +3 -1
- package/dist/templates/workspace-root/AGENTS.md +3 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/package.json +2 -1
- package/src/cli/create.ts +23 -0
- package/src/cli/skills.ts +24 -0
- package/src/db/request-telemetry.ts +32 -8
- package/src/settings/store.ts +15 -6
- package/src/shared/optional-node-builtins.ts +66 -0
- package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/src/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
- package/src/templates/chat/AGENTS.md +4 -1
- package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/src/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
- package/src/templates/default/AGENTS.md +4 -1
- package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/src/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
- package/src/templates/headless/AGENTS.md +5 -1
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +26 -0
- package/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
- package/src/templates/workspace-core/AGENTS.md +3 -1
- package/src/templates/workspace-root/AGENTS.md +3 -1
- package/src/vite/client.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.114.
|
|
3
|
+
"version": "0.114.3",
|
|
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": {
|
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"./application-state": "./dist/application-state/index.js",
|
|
160
160
|
"./settings": "./dist/settings/index.js",
|
|
161
161
|
"./feature-flags": "./dist/feature-flags/index.js",
|
|
162
|
+
"./feature-flags/registry": "./dist/feature-flags/registry.js",
|
|
162
163
|
"./feature-flags/actions/get-feature-flags": "./dist/feature-flags/actions/get-feature-flags.js",
|
|
163
164
|
"./feature-flags/actions/list-feature-flags": "./dist/feature-flags/actions/list-feature-flags.js",
|
|
164
165
|
"./feature-flags/actions/set-feature-flag": "./dist/feature-flags/actions/set-feature-flag.js",
|
package/src/cli/create.ts
CHANGED
|
@@ -1697,10 +1697,33 @@ function fixPackageJsonName(
|
|
|
1697
1697
|
) {
|
|
1698
1698
|
pkg.description = defaultPackageDescriptionForScaffold(name);
|
|
1699
1699
|
}
|
|
1700
|
+
const scaffoldGuidance = scaffoldGuidanceForTemplate(templateName);
|
|
1701
|
+
if (scaffoldGuidance) {
|
|
1702
|
+
const agentNative =
|
|
1703
|
+
pkg["agent-native"] &&
|
|
1704
|
+
typeof pkg["agent-native"] === "object" &&
|
|
1705
|
+
!Array.isArray(pkg["agent-native"])
|
|
1706
|
+
? pkg["agent-native"]
|
|
1707
|
+
: {};
|
|
1708
|
+
agentNative.scaffold = {
|
|
1709
|
+
template: trackingTemplateName(templateName),
|
|
1710
|
+
frameworkSkills: scaffoldGuidance,
|
|
1711
|
+
};
|
|
1712
|
+
pkg["agent-native"] = agentNative;
|
|
1713
|
+
}
|
|
1700
1714
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
1701
1715
|
} catch {}
|
|
1702
1716
|
}
|
|
1703
1717
|
|
|
1718
|
+
function scaffoldGuidanceForTemplate(
|
|
1719
|
+
templateName: string | undefined,
|
|
1720
|
+
): "default" | "headless" | undefined {
|
|
1721
|
+
if (!templateName || templateName.startsWith("github:")) return undefined;
|
|
1722
|
+
const normalized = normalizeTemplateName(templateName);
|
|
1723
|
+
if (normalized === "headless") return "headless";
|
|
1724
|
+
return getTemplate(normalized) ? "default" : undefined;
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1704
1727
|
function fixWebManifestName(
|
|
1705
1728
|
appDir: string,
|
|
1706
1729
|
name: string,
|
package/src/cli/skills.ts
CHANGED
|
@@ -1580,6 +1580,27 @@ function hasAgentNativeCoreDependency(
|
|
|
1580
1580
|
return false;
|
|
1581
1581
|
}
|
|
1582
1582
|
|
|
1583
|
+
function markedScaffoldGuidanceTemplate(
|
|
1584
|
+
pkg: Record<string, unknown> | undefined,
|
|
1585
|
+
): "headless" | "default" | undefined {
|
|
1586
|
+
const agentNative = pkg?.["agent-native"];
|
|
1587
|
+
if (
|
|
1588
|
+
!agentNative ||
|
|
1589
|
+
typeof agentNative !== "object" ||
|
|
1590
|
+
Array.isArray(agentNative)
|
|
1591
|
+
) {
|
|
1592
|
+
return undefined;
|
|
1593
|
+
}
|
|
1594
|
+
const scaffold = (agentNative as Record<string, unknown>).scaffold;
|
|
1595
|
+
if (!scaffold || typeof scaffold !== "object" || Array.isArray(scaffold)) {
|
|
1596
|
+
return undefined;
|
|
1597
|
+
}
|
|
1598
|
+
const frameworkSkills = (scaffold as Record<string, unknown>).frameworkSkills;
|
|
1599
|
+
return frameworkSkills === "headless" || frameworkSkills === "default"
|
|
1600
|
+
? frameworkSkills
|
|
1601
|
+
: undefined;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1583
1604
|
function findWorkspaceCorePackageDir(
|
|
1584
1605
|
workspaceRoot: string,
|
|
1585
1606
|
workspaceCoreName: string,
|
|
@@ -1634,6 +1655,9 @@ function detectStandaloneScaffoldTemplate(
|
|
|
1634
1655
|
return undefined;
|
|
1635
1656
|
}
|
|
1636
1657
|
|
|
1658
|
+
const markedTemplate = markedScaffoldGuidanceTemplate(pkg);
|
|
1659
|
+
if (markedTemplate) return markedTemplate;
|
|
1660
|
+
|
|
1637
1661
|
const hasAppDir = fs.existsSync(path.join(projectRoot, "app"));
|
|
1638
1662
|
const hasHeadlessHello = fs.existsSync(
|
|
1639
1663
|
path.join(projectRoot, "actions", "hello.ts"),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAsyncLocalStorageCtor } from "../shared/optional-node-builtins.js";
|
|
2
2
|
|
|
3
3
|
export type DatabaseOperationKind = "connect" | "query";
|
|
4
4
|
|
|
@@ -30,15 +30,39 @@ interface StartupDatabaseTelemetryState {
|
|
|
30
30
|
claimed: boolean;
|
|
31
31
|
telemetry: DatabaseRequestTelemetry;
|
|
32
32
|
}
|
|
33
|
+
interface TelemetryStorage {
|
|
34
|
+
getStore(): DatabaseRequestTelemetry | undefined;
|
|
35
|
+
run<T>(store: DatabaseRequestTelemetry, fn: () => T): T;
|
|
36
|
+
enterWith(store: DatabaseRequestTelemetry): void;
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
type GlobalWithDatabaseTelemetry = typeof globalThis & {
|
|
34
|
-
[STORAGE_KEY]?:
|
|
40
|
+
[STORAGE_KEY]?: TelemetryStorage;
|
|
35
41
|
[STARTUP_STATE_KEY]?: StartupDatabaseTelemetryState;
|
|
36
42
|
};
|
|
37
43
|
|
|
38
44
|
const globalRef = globalThis as GlobalWithDatabaseTelemetry;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
|
|
46
|
+
// AsyncLocalStorage is resolved lazily, never at module load: this module can
|
|
47
|
+
// land in the browser dev graph, where a top-level `new AsyncLocalStorage()`
|
|
48
|
+
// would throw against Vite's externalized `node:async_hooks` stub. On non-Node
|
|
49
|
+
// runtimes telemetry no-ops.
|
|
50
|
+
const NOOP_STORAGE: TelemetryStorage = {
|
|
51
|
+
getStore: () => undefined,
|
|
52
|
+
run: (_store, fn) => fn(),
|
|
53
|
+
enterWith: () => {},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
function getStorage(): TelemetryStorage {
|
|
57
|
+
const existing = globalRef[STORAGE_KEY];
|
|
58
|
+
if (existing) return existing;
|
|
59
|
+
const Ctor = getAsyncLocalStorageCtor();
|
|
60
|
+
const created: TelemetryStorage = Ctor
|
|
61
|
+
? new Ctor<DatabaseRequestTelemetry>()
|
|
62
|
+
: NOOP_STORAGE;
|
|
63
|
+
globalRef[STORAGE_KEY] = created;
|
|
64
|
+
return created;
|
|
65
|
+
}
|
|
42
66
|
|
|
43
67
|
export function createDatabaseRequestTelemetry(): DatabaseRequestTelemetry {
|
|
44
68
|
return {
|
|
@@ -66,7 +90,7 @@ const startupState =
|
|
|
66
90
|
});
|
|
67
91
|
|
|
68
92
|
function currentDatabaseTelemetry(): DatabaseRequestTelemetry | undefined {
|
|
69
|
-
const requestTelemetry =
|
|
93
|
+
const requestTelemetry = getStorage().getStore();
|
|
70
94
|
if (requestTelemetry) return requestTelemetry;
|
|
71
95
|
if (!startupState.claimed && Date.now() <= startupState.captureUntil) {
|
|
72
96
|
return startupState.telemetry;
|
|
@@ -86,13 +110,13 @@ export function runWithDatabaseRequestTelemetry<T>(
|
|
|
86
110
|
telemetry: DatabaseRequestTelemetry,
|
|
87
111
|
fn: () => T,
|
|
88
112
|
): T {
|
|
89
|
-
return
|
|
113
|
+
return getStorage().run(telemetry, fn);
|
|
90
114
|
}
|
|
91
115
|
|
|
92
116
|
export function enterDatabaseRequestTelemetry(
|
|
93
117
|
telemetry: DatabaseRequestTelemetry,
|
|
94
118
|
): void {
|
|
95
|
-
|
|
119
|
+
getStorage().enterWith(telemetry);
|
|
96
120
|
}
|
|
97
121
|
|
|
98
122
|
export function beginDatabaseOperation(
|
package/src/settings/store.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
1
|
+
import type { EventEmitter } from "node:events";
|
|
2
2
|
|
|
3
3
|
import { getDbExec, isPostgres, intType } from "../db/client.js";
|
|
4
4
|
import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
|
|
5
5
|
import { widenIntColumnsToBigInt } from "../db/widen-columns.js";
|
|
6
6
|
import { getRequestContext } from "../server/request-context.js";
|
|
7
|
+
import { createEventEmitter } from "../shared/optional-node-builtins.js";
|
|
7
8
|
|
|
8
9
|
let _initPromise: Promise<void> | undefined;
|
|
9
10
|
|
|
@@ -29,12 +30,20 @@ function requestSettingsCache(): Map<string, string | null> | null {
|
|
|
29
30
|
return cache;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
// Created lazily so this module can be evaluated in the browser dev graph
|
|
34
|
+
// without a top-level `new EventEmitter()` tripping Vite's externalized
|
|
35
|
+
// `node:events` stub. The emitter drives server-side SSE fan-out only.
|
|
36
|
+
let _emitter: EventEmitter | undefined;
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
function settingsEmitter(): EventEmitter {
|
|
39
|
+
if (!_emitter) _emitter = createEventEmitter();
|
|
35
40
|
return _emitter;
|
|
36
41
|
}
|
|
37
42
|
|
|
43
|
+
export function getSettingsEmitter(): EventEmitter {
|
|
44
|
+
return settingsEmitter();
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
function settingsTable(): string {
|
|
39
48
|
return isPostgres() ? "public.settings" : "settings";
|
|
40
49
|
}
|
|
@@ -174,7 +183,7 @@ export async function mutateSetting(
|
|
|
174
183
|
});
|
|
175
184
|
if (result.rowsAffected === 0) continue;
|
|
176
185
|
requestSettingsCache()?.set(key, nextRaw);
|
|
177
|
-
|
|
186
|
+
settingsEmitter().emit("settings", {
|
|
178
187
|
source: "settings",
|
|
179
188
|
type: "change",
|
|
180
189
|
key,
|
|
@@ -200,7 +209,7 @@ export async function putSetting(
|
|
|
200
209
|
args: [key, JSON.stringify(value), Date.now()],
|
|
201
210
|
});
|
|
202
211
|
requestSettingsCache()?.set(key, JSON.stringify(value));
|
|
203
|
-
|
|
212
|
+
settingsEmitter().emit("settings", {
|
|
204
213
|
source: "settings",
|
|
205
214
|
type: "change",
|
|
206
215
|
key,
|
|
@@ -221,7 +230,7 @@ export async function deleteSetting(
|
|
|
221
230
|
});
|
|
222
231
|
requestSettingsCache()?.set(key, null);
|
|
223
232
|
if (result.rowsAffected > 0) {
|
|
224
|
-
|
|
233
|
+
settingsEmitter().emit("settings", {
|
|
225
234
|
source: "settings",
|
|
226
235
|
type: "delete",
|
|
227
236
|
key,
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe accessors for optional Node builtins.
|
|
3
|
+
*
|
|
4
|
+
* `node:async_hooks` and `node:events` are server-only, but the modules that
|
|
5
|
+
* use them (db telemetry, settings/resource emitters) can land in the browser
|
|
6
|
+
* dev graph before tree-shaking runs. A static `import { X } from "node:..."`
|
|
7
|
+
* resolves to Vite's externalized stub and throws the instant the value is
|
|
8
|
+
* touched at module load. We read the builtin through `process.getBuiltinModule`
|
|
9
|
+
* instead — the same guard `server/request-context.ts` uses — so there is no
|
|
10
|
+
* static `node:` import to evaluate in the browser, and callers fall back to a
|
|
11
|
+
* no-op on non-Node runtimes (browser, or Node without getBuiltinModule).
|
|
12
|
+
*/
|
|
13
|
+
import type { AsyncLocalStorage } from "node:async_hooks";
|
|
14
|
+
import type { EventEmitter } from "node:events";
|
|
15
|
+
|
|
16
|
+
type BuiltinProcess = {
|
|
17
|
+
versions?: { node?: string };
|
|
18
|
+
getBuiltinModule?: (name: string) => unknown;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function nodeBuiltin<T>(name: string): T | undefined {
|
|
22
|
+
const proc =
|
|
23
|
+
typeof process === "undefined" ? undefined : (process as BuiltinProcess);
|
|
24
|
+
if (
|
|
25
|
+
typeof window !== "undefined" ||
|
|
26
|
+
!proc ||
|
|
27
|
+
!proc.versions?.node ||
|
|
28
|
+
typeof proc.getBuiltinModule !== "function"
|
|
29
|
+
) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return proc.getBuiltinModule(name) as T | undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type AsyncLocalStorageCtor = new <T>() => AsyncLocalStorage<T>;
|
|
36
|
+
|
|
37
|
+
export function getAsyncLocalStorageCtor(): AsyncLocalStorageCtor | undefined {
|
|
38
|
+
return nodeBuiltin<{ AsyncLocalStorage: AsyncLocalStorageCtor }>(
|
|
39
|
+
"node:async_hooks",
|
|
40
|
+
)?.AsyncLocalStorage;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type EventEmitterCtor = new () => EventEmitter;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns a real Node EventEmitter on Node, or a no-op emitter elsewhere. The
|
|
47
|
+
* emitters that use this drive server-side SSE fan-out; nothing subscribes in
|
|
48
|
+
* the browser, so the no-op fallback is inert rather than wrong.
|
|
49
|
+
*/
|
|
50
|
+
export function createEventEmitter(): EventEmitter {
|
|
51
|
+
const Ctor = nodeBuiltin<{ EventEmitter: EventEmitterCtor }>(
|
|
52
|
+
"node:events",
|
|
53
|
+
)?.EventEmitter;
|
|
54
|
+
if (Ctor) return new Ctor();
|
|
55
|
+
const noop = {
|
|
56
|
+
on: () => noop,
|
|
57
|
+
off: () => noop,
|
|
58
|
+
once: () => noop,
|
|
59
|
+
addListener: () => noop,
|
|
60
|
+
removeListener: () => noop,
|
|
61
|
+
removeAllListeners: () => noop,
|
|
62
|
+
setMaxListeners: () => noop,
|
|
63
|
+
emit: () => false,
|
|
64
|
+
};
|
|
65
|
+
return noop as unknown as EventEmitter;
|
|
66
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-native-toolkit
|
|
3
|
+
description: >-
|
|
4
|
+
Inventory and ownership rules for shared Agent Native workspace UI. Use
|
|
5
|
+
before building app chrome, settings, navigation, sharing, collaboration,
|
|
6
|
+
setup, history, comments, chat rails, agent UX, or repeated workspace behavior.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Agent-Native Toolkit
|
|
13
|
+
|
|
14
|
+
Use this skill when deciding whether app chrome, settings, collaboration,
|
|
15
|
+
sharing, navigation, organization, setup, history, comments, or agent UX should
|
|
16
|
+
be built app-locally or moved into reusable framework/toolkit pieces.
|
|
17
|
+
|
|
18
|
+
## Core Rule
|
|
19
|
+
|
|
20
|
+
Apps own domain models, domain actions, and product-specific workflows. The
|
|
21
|
+
framework and `@agent-native/toolkit` own repeated workspace behavior users
|
|
22
|
+
expect to work the same everywhere.
|
|
23
|
+
|
|
24
|
+
Move behavior into shared toolkit primitives when it is:
|
|
25
|
+
|
|
26
|
+
- workspace-wide, such as settings, nav, search, org membership, or setup
|
|
27
|
+
- agent-visible, such as context, actions, run progress, or proof-of-done
|
|
28
|
+
- governed, such as secrets, permissions, sharing, audit, or billing
|
|
29
|
+
- repeated by two or more apps
|
|
30
|
+
- not tied to one domain model
|
|
31
|
+
|
|
32
|
+
Keep behavior app-local when the abstraction would hide important domain
|
|
33
|
+
language or make a simple app-specific workflow harder to understand.
|
|
34
|
+
|
|
35
|
+
## Discover Before Building
|
|
36
|
+
|
|
37
|
+
Before creating an app-local version of repeated workspace or agent UI:
|
|
38
|
+
|
|
39
|
+
1. Check the reusable kits below and the installed package documentation.
|
|
40
|
+
2. Search installed public components and source with `docs-search` and
|
|
41
|
+
`source-search`.
|
|
42
|
+
3. Run `agent-native eject --list` to see the version-matched units published
|
|
43
|
+
by the packages installed in this app.
|
|
44
|
+
4. Read `customizing-agent-native` and configure, compose, or eject the
|
|
45
|
+
smallest unit instead of recreating shared behavior from memory.
|
|
46
|
+
|
|
47
|
+
Use public package exports at runtime. Published source and ejection manifests
|
|
48
|
+
are discovery and ownership-transfer mechanisms, not private runtime APIs.
|
|
49
|
+
|
|
50
|
+
## Settings Direction
|
|
51
|
+
|
|
52
|
+
Durable settings belong in the Settings app or a registered settings route. The
|
|
53
|
+
agent sidebar should not become a second settings app. It can show contextual
|
|
54
|
+
quick controls and deep links such as:
|
|
55
|
+
|
|
56
|
+
- `/settings/ai`
|
|
57
|
+
- `/settings/connections`
|
|
58
|
+
- `/settings/secrets`
|
|
59
|
+
- `/settings/usage`
|
|
60
|
+
- `/settings/apps/:appId`
|
|
61
|
+
|
|
62
|
+
When adding a new API key, OAuth grant, provider connection, model selector, app
|
|
63
|
+
preference, notification preference, or usage/billing surface, register it as a
|
|
64
|
+
settings tab or app settings panel first. Only add sidebar UI when it is needed
|
|
65
|
+
in the moment of agent use.
|
|
66
|
+
|
|
67
|
+
## Reusable Kits
|
|
68
|
+
|
|
69
|
+
- **Settings kit**: a searchable settings page with account, workspace, AI
|
|
70
|
+
models, LLM keys, connections, secrets, usage, notifications, changelog, and
|
|
71
|
+
app-specific panels. Search is on by default; register a `SettingsSearchEntry`
|
|
72
|
+
per control so users find settings by name across tabs.
|
|
73
|
+
- **Collaboration kit**: Yjs docs, presence, agent presence, live cursors,
|
|
74
|
+
remote selections, recent edit highlights, real-time sync indicators, and
|
|
75
|
+
undo/redo grouping.
|
|
76
|
+
- **Sharing kit**: private/workspace/org/public-link access, invites, roles,
|
|
77
|
+
expirations, agent-readable links, and resource registration.
|
|
78
|
+
- **Navigation and command kit**: app shell, side nav, breadcrumbs, app switcher,
|
|
79
|
+
command palette entries, recent resources, pinned resources, and global search.
|
|
80
|
+
- **Organization kit**: folders, tags, favorites, archive, trash, ownership,
|
|
81
|
+
membership, and common resource metadata.
|
|
82
|
+
- **Setup and connections kit**: declarative setup requirements, model readiness,
|
|
83
|
+
missing-secret states, OAuth grants, and provider connection health.
|
|
84
|
+
- **Agent UX kit**: sidebar, composer, staged context, mentions, voice, human
|
|
85
|
+
approval, generative UI, progress, and screen-state exposure.
|
|
86
|
+
- **Chat history kit**: presentational chat lists and recent-chat rails belong
|
|
87
|
+
in Toolkit; Core keeps thread persistence, agent execution, transport, and
|
|
88
|
+
page-to-sidebar handoff. Apps inject routing, labels, and domain actions.
|
|
89
|
+
- **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
|
|
90
|
+
`@agent-native/core/client`) with Context, Files, Connections, Jobs, and
|
|
91
|
+
Access tabs plus a Personal/Organization scope toggle. The canonical home
|
|
92
|
+
for context transparency, MCP servers, A2A remote agents, recurring
|
|
93
|
+
jobs/automations, and external-client connect flows. See the `agent-page`
|
|
94
|
+
skill.
|
|
95
|
+
- **History and recovery kit**: audit log, activity feed, version history,
|
|
96
|
+
checkpoints, undo, redo, restore, and proof-of-done.
|
|
97
|
+
- **Comments and review kit**: anchored comments, pins, mentions, review
|
|
98
|
+
requests, resolved threads, agent follow-up tasks, and notifications.
|
|
99
|
+
- **Workflow and observability kit**: notifications, approvals, scheduled work,
|
|
100
|
+
background runs, recurring jobs, traces, evals, feedback, and run timelines.
|
|
101
|
+
|
|
102
|
+
## Implementation Checklist
|
|
103
|
+
|
|
104
|
+
When adding or refactoring one of these areas:
|
|
105
|
+
|
|
106
|
+
1. Search existing framework and template code for duplicated UI or actions.
|
|
107
|
+
2. Decide the shared contract: data shape, action API, React component/hook, and
|
|
108
|
+
app adapter points.
|
|
109
|
+
3. Keep shared data provider-agnostic and scoped by auth/sharing rules.
|
|
110
|
+
4. Expose the same capability to the UI and agent through actions or documented
|
|
111
|
+
client helpers.
|
|
112
|
+
5. Register app-specific labels, routes, resource adapters, and settings panels
|
|
113
|
+
instead of hardcoding app names in core UI.
|
|
114
|
+
6. Update docs and relevant skills so future apps discover the shared path.
|
|
115
|
+
7. Keep the component easy to adopt piecemeal: expose props/slots first and
|
|
116
|
+
ship readable source plus a complete ejection unit so apps can take ownership
|
|
117
|
+
of the smallest feature when needed. See `customizing-agent-native` for the
|
|
118
|
+
configure → compose → eject → propose seam ladder.
|
|
119
|
+
|
|
120
|
+
## Related Skills
|
|
121
|
+
|
|
122
|
+
Read these alongside this skill when the work touches the specific area:
|
|
123
|
+
|
|
124
|
+
- `sharing`
|
|
125
|
+
- `real-time-collab`
|
|
126
|
+
- `real-time-sync`
|
|
127
|
+
- `client-side-routing`
|
|
128
|
+
- `context-awareness`
|
|
129
|
+
- `onboarding`
|
|
130
|
+
- `secrets`
|
|
131
|
+
- `audit-log`
|
|
132
|
+
- `observability`
|
|
133
|
+
- `frontend-design`
|
|
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
|
|
|
37
37
|
same stable key. Flags are boolean and default-off.
|
|
38
38
|
|
|
39
39
|
```ts
|
|
40
|
-
import { defineFeatureFlag } from "@agent-native/core/feature-flags";
|
|
40
|
+
import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
|
|
41
41
|
|
|
42
42
|
export const FULL_APP_BUILDING = defineFeatureFlag({
|
|
43
43
|
key: "full-app-building",
|
|
@@ -53,6 +53,8 @@ workflow needs durable UI around the conversation.
|
|
|
53
53
|
first-party template implementation examples.
|
|
54
54
|
- Prefer those installed docs over memory or public docs when package APIs,
|
|
55
55
|
generated-app conventions, workspaces, actions, or agent surfaces are involved.
|
|
56
|
+
- Before building common workspace or agent UI, read `agent-native-toolkit` to
|
|
57
|
+
inventory existing public kits and installed package seams.
|
|
56
58
|
- Read `customizing-agent-native` before overriding the chat shell or shared UI.
|
|
57
59
|
Keep Core thread/runtime behavior and use the supported ladder: configure →
|
|
58
60
|
compose → eject the smallest presentation unit → propose a shared seam.
|
|
@@ -61,6 +63,7 @@ workflow needs durable UI around the conversation.
|
|
|
61
63
|
## Skills
|
|
62
64
|
|
|
63
65
|
Read the relevant root skill before implementation: `adding-a-feature`,
|
|
64
|
-
`actions`, `agent-native-docs`, `
|
|
66
|
+
`actions`, `agent-native-docs`, `agent-native-toolkit`,
|
|
67
|
+
`customizing-agent-native`, `storing-data`,
|
|
65
68
|
`real-time-sync`, `security`, `delegate-to-agent`, `frontend-design`, `shadcn-ui`, and
|
|
66
69
|
`self-modifying-code`.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-native-toolkit
|
|
3
|
+
description: >-
|
|
4
|
+
Inventory and ownership rules for shared Agent Native workspace UI. Use
|
|
5
|
+
before building app chrome, settings, navigation, sharing, collaboration,
|
|
6
|
+
setup, history, comments, chat rails, agent UX, or repeated workspace behavior.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Agent-Native Toolkit
|
|
13
|
+
|
|
14
|
+
Use this skill when deciding whether app chrome, settings, collaboration,
|
|
15
|
+
sharing, navigation, organization, setup, history, comments, or agent UX should
|
|
16
|
+
be built app-locally or moved into reusable framework/toolkit pieces.
|
|
17
|
+
|
|
18
|
+
## Core Rule
|
|
19
|
+
|
|
20
|
+
Apps own domain models, domain actions, and product-specific workflows. The
|
|
21
|
+
framework and `@agent-native/toolkit` own repeated workspace behavior users
|
|
22
|
+
expect to work the same everywhere.
|
|
23
|
+
|
|
24
|
+
Move behavior into shared toolkit primitives when it is:
|
|
25
|
+
|
|
26
|
+
- workspace-wide, such as settings, nav, search, org membership, or setup
|
|
27
|
+
- agent-visible, such as context, actions, run progress, or proof-of-done
|
|
28
|
+
- governed, such as secrets, permissions, sharing, audit, or billing
|
|
29
|
+
- repeated by two or more apps
|
|
30
|
+
- not tied to one domain model
|
|
31
|
+
|
|
32
|
+
Keep behavior app-local when the abstraction would hide important domain
|
|
33
|
+
language or make a simple app-specific workflow harder to understand.
|
|
34
|
+
|
|
35
|
+
## Discover Before Building
|
|
36
|
+
|
|
37
|
+
Before creating an app-local version of repeated workspace or agent UI:
|
|
38
|
+
|
|
39
|
+
1. Check the reusable kits below and the installed package documentation.
|
|
40
|
+
2. Search installed public components and source with `docs-search` and
|
|
41
|
+
`source-search`.
|
|
42
|
+
3. Run `agent-native eject --list` to see the version-matched units published
|
|
43
|
+
by the packages installed in this app.
|
|
44
|
+
4. Read `customizing-agent-native` and configure, compose, or eject the
|
|
45
|
+
smallest unit instead of recreating shared behavior from memory.
|
|
46
|
+
|
|
47
|
+
Use public package exports at runtime. Published source and ejection manifests
|
|
48
|
+
are discovery and ownership-transfer mechanisms, not private runtime APIs.
|
|
49
|
+
|
|
50
|
+
## Settings Direction
|
|
51
|
+
|
|
52
|
+
Durable settings belong in the Settings app or a registered settings route. The
|
|
53
|
+
agent sidebar should not become a second settings app. It can show contextual
|
|
54
|
+
quick controls and deep links such as:
|
|
55
|
+
|
|
56
|
+
- `/settings/ai`
|
|
57
|
+
- `/settings/connections`
|
|
58
|
+
- `/settings/secrets`
|
|
59
|
+
- `/settings/usage`
|
|
60
|
+
- `/settings/apps/:appId`
|
|
61
|
+
|
|
62
|
+
When adding a new API key, OAuth grant, provider connection, model selector, app
|
|
63
|
+
preference, notification preference, or usage/billing surface, register it as a
|
|
64
|
+
settings tab or app settings panel first. Only add sidebar UI when it is needed
|
|
65
|
+
in the moment of agent use.
|
|
66
|
+
|
|
67
|
+
## Reusable Kits
|
|
68
|
+
|
|
69
|
+
- **Settings kit**: a searchable settings page with account, workspace, AI
|
|
70
|
+
models, LLM keys, connections, secrets, usage, notifications, changelog, and
|
|
71
|
+
app-specific panels. Search is on by default; register a `SettingsSearchEntry`
|
|
72
|
+
per control so users find settings by name across tabs.
|
|
73
|
+
- **Collaboration kit**: Yjs docs, presence, agent presence, live cursors,
|
|
74
|
+
remote selections, recent edit highlights, real-time sync indicators, and
|
|
75
|
+
undo/redo grouping.
|
|
76
|
+
- **Sharing kit**: private/workspace/org/public-link access, invites, roles,
|
|
77
|
+
expirations, agent-readable links, and resource registration.
|
|
78
|
+
- **Navigation and command kit**: app shell, side nav, breadcrumbs, app switcher,
|
|
79
|
+
command palette entries, recent resources, pinned resources, and global search.
|
|
80
|
+
- **Organization kit**: folders, tags, favorites, archive, trash, ownership,
|
|
81
|
+
membership, and common resource metadata.
|
|
82
|
+
- **Setup and connections kit**: declarative setup requirements, model readiness,
|
|
83
|
+
missing-secret states, OAuth grants, and provider connection health.
|
|
84
|
+
- **Agent UX kit**: sidebar, composer, staged context, mentions, voice, human
|
|
85
|
+
approval, generative UI, progress, and screen-state exposure.
|
|
86
|
+
- **Chat history kit**: presentational chat lists and recent-chat rails belong
|
|
87
|
+
in Toolkit; Core keeps thread persistence, agent execution, transport, and
|
|
88
|
+
page-to-sidebar handoff. Apps inject routing, labels, and domain actions.
|
|
89
|
+
- **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
|
|
90
|
+
`@agent-native/core/client`) with Context, Files, Connections, Jobs, and
|
|
91
|
+
Access tabs plus a Personal/Organization scope toggle. The canonical home
|
|
92
|
+
for context transparency, MCP servers, A2A remote agents, recurring
|
|
93
|
+
jobs/automations, and external-client connect flows. See the `agent-page`
|
|
94
|
+
skill.
|
|
95
|
+
- **History and recovery kit**: audit log, activity feed, version history,
|
|
96
|
+
checkpoints, undo, redo, restore, and proof-of-done.
|
|
97
|
+
- **Comments and review kit**: anchored comments, pins, mentions, review
|
|
98
|
+
requests, resolved threads, agent follow-up tasks, and notifications.
|
|
99
|
+
- **Workflow and observability kit**: notifications, approvals, scheduled work,
|
|
100
|
+
background runs, recurring jobs, traces, evals, feedback, and run timelines.
|
|
101
|
+
|
|
102
|
+
## Implementation Checklist
|
|
103
|
+
|
|
104
|
+
When adding or refactoring one of these areas:
|
|
105
|
+
|
|
106
|
+
1. Search existing framework and template code for duplicated UI or actions.
|
|
107
|
+
2. Decide the shared contract: data shape, action API, React component/hook, and
|
|
108
|
+
app adapter points.
|
|
109
|
+
3. Keep shared data provider-agnostic and scoped by auth/sharing rules.
|
|
110
|
+
4. Expose the same capability to the UI and agent through actions or documented
|
|
111
|
+
client helpers.
|
|
112
|
+
5. Register app-specific labels, routes, resource adapters, and settings panels
|
|
113
|
+
instead of hardcoding app names in core UI.
|
|
114
|
+
6. Update docs and relevant skills so future apps discover the shared path.
|
|
115
|
+
7. Keep the component easy to adopt piecemeal: expose props/slots first and
|
|
116
|
+
ship readable source plus a complete ejection unit so apps can take ownership
|
|
117
|
+
of the smallest feature when needed. See `customizing-agent-native` for the
|
|
118
|
+
configure → compose → eject → propose seam ladder.
|
|
119
|
+
|
|
120
|
+
## Related Skills
|
|
121
|
+
|
|
122
|
+
Read these alongside this skill when the work touches the specific area:
|
|
123
|
+
|
|
124
|
+
- `sharing`
|
|
125
|
+
- `real-time-collab`
|
|
126
|
+
- `real-time-sync`
|
|
127
|
+
- `client-side-routing`
|
|
128
|
+
- `context-awareness`
|
|
129
|
+
- `onboarding`
|
|
130
|
+
- `secrets`
|
|
131
|
+
- `audit-log`
|
|
132
|
+
- `observability`
|
|
133
|
+
- `frontend-design`
|
|
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
|
|
|
37
37
|
same stable key. Flags are boolean and default-off.
|
|
38
38
|
|
|
39
39
|
```ts
|
|
40
|
-
import { defineFeatureFlag } from "@agent-native/core/feature-flags";
|
|
40
|
+
import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
|
|
41
41
|
|
|
42
42
|
export const FULL_APP_BUILDING = defineFeatureFlag({
|
|
43
43
|
key: "full-app-building",
|
|
@@ -34,7 +34,9 @@ first-party template patterns ships in `node_modules/@agent-native/core/corpus`.
|
|
|
34
34
|
`node_modules/@agent-native/core/docs/content/` directly with `rg`. Search
|
|
35
35
|
`node_modules/@agent-native/core/corpus/` for source examples.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Before building common workspace or agent UI, read `agent-native-toolkit` to
|
|
38
|
+
inventory existing public kits and installed package seams. When intentionally
|
|
39
|
+
customizing shared UI, read `customizing-agent-native`.
|
|
38
40
|
Use the supported ladder: configure → compose → eject the smallest unit →
|
|
39
41
|
propose a shared seam. Preview `agent-native eject <unit>` before `--apply`,
|
|
40
42
|
commit `agent-native.ejections.json`, and never edit `node_modules`, deep-import
|
|
@@ -164,6 +166,7 @@ Skills in `.agents/skills/` provide detailed guidance for each architectural rul
|
|
|
164
166
|
| Skill | When to read |
|
|
165
167
|
| -------------------------- | --------------------------------------------------------------------------------- |
|
|
166
168
|
| `agent-native-docs` | Before using advanced Agent Native framework APIs or generated-app features |
|
|
169
|
+
| `agent-native-toolkit` | Before building common workspace, chat, settings, navigation, or collaboration UI |
|
|
167
170
|
| `customizing-agent-native` | Before configuring, composing, or ejecting shared Agent Native features |
|
|
168
171
|
| `adding-a-feature` | **Read first when adding ANY new feature** — the four-area parity checklist |
|
|
169
172
|
| `feature-flags` | Before shipping a staged production rollout or replacing a compile-time switch |
|