@cef-ai/cli 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/cli-program.d.ts +6 -5
  2. package/dist/cli-program.d.ts.map +1 -1
  3. package/dist/cli-program.js +66 -17
  4. package/dist/cli-program.js.map +1 -1
  5. package/dist/commands/build.d.ts +11 -0
  6. package/dist/commands/build.d.ts.map +1 -1
  7. package/dist/commands/build.js +48 -8
  8. package/dist/commands/build.js.map +1 -1
  9. package/dist/commands/dev.d.ts +61 -0
  10. package/dist/commands/dev.d.ts.map +1 -0
  11. package/dist/commands/dev.js +239 -0
  12. package/dist/commands/dev.js.map +1 -0
  13. package/dist/commands/init.d.ts.map +1 -1
  14. package/dist/commands/init.js +33 -4
  15. package/dist/commands/init.js.map +1 -1
  16. package/dist/lib/env.d.ts +71 -0
  17. package/dist/lib/env.d.ts.map +1 -0
  18. package/dist/lib/env.js +78 -0
  19. package/dist/lib/env.js.map +1 -0
  20. package/dist/lib/widget-manifest.d.ts +48 -0
  21. package/dist/lib/widget-manifest.d.ts.map +1 -0
  22. package/dist/lib/widget-manifest.js +91 -0
  23. package/dist/lib/widget-manifest.js.map +1 -0
  24. package/dist/lib/widget-runtime-bundle.d.ts +7 -0
  25. package/dist/lib/widget-runtime-bundle.d.ts.map +1 -0
  26. package/dist/lib/widget-runtime-bundle.js +31 -0
  27. package/dist/lib/widget-runtime-bundle.js.map +1 -0
  28. package/dist/lib.d.ts +4 -0
  29. package/dist/lib.d.ts.map +1 -1
  30. package/dist/lib.js +2 -0
  31. package/dist/lib.js.map +1 -1
  32. package/package.json +4 -3
  33. package/templates/hello-world/cef.config.ts +38 -3
  34. package/templates/hello-world/package.json +6 -0
  35. package/templates/hello-world/src/agent.ts +28 -10
  36. package/templates/hello-world/test/agent.test.ts +13 -0
  37. package/templates/hello-world/tsconfig.json +1 -1
  38. package/templates/hello-world/widgets/hello/app.js +117 -7
  39. package/templates/hello-world/widgets/hello/index.html +20 -0
  40. package/templates/hello-world/widgets/hello/hello.html +0 -5
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Widget manifest builder (build-time tooling).
3
+ *
4
+ * `@cef-ai/widget-runtime` *reads* a `WidgetManifest` at boot but never builds
5
+ * one — that is the CLI's job. This module assembles the arguments for the
6
+ * runtime's `buildWidgetManifest` from a `cef.config.ts` widget declaration, the
7
+ * resolved `--env` endpoints (see `./env.ts`), and the agent's AS pubkey.
8
+ *
9
+ * Used by both `cef build` (bakes the manifest into `dist/…/widgets/<id>/`) and
10
+ * `cef dev` (serves it inline), so the embedded and standalone paths get an
11
+ * identical manifest.
12
+ */
13
+ import { buildWidgetManifest, } from "@cef-ai/widget-runtime/build-tools";
14
+ import { envConfig, resolveEnv } from "./env.js";
15
+ /** Runtime-known widget kinds. `WidgetDecl.kind` is free-form, so unrecognized
16
+ * values are dropped from the baked manifest (see below). */
17
+ const KNOWN_KINDS = new Set([
18
+ "record",
19
+ "list",
20
+ "dashboard",
21
+ "submit",
22
+ "conversation",
23
+ "custom",
24
+ "composite",
25
+ ]);
26
+ /**
27
+ * Build a `WidgetManifest` for one widget declaration + resolved env.
28
+ *
29
+ * Deliberately tolerant: an unknown `kind` (WidgetDecl.kind is free-form) is
30
+ * dropped with a warning rather than throwing, so a `cef build` never fails on
31
+ * a widget the runtime doesn't render as a config-driven kind — the widget can
32
+ * still query the cubby via `window.WidgetRuntime`.
33
+ */
34
+ export function buildWidgetManifestForDecl(args) {
35
+ const { widget, alias } = args;
36
+ const env = resolveEnv(args.env);
37
+ const cfg = envConfig(args.env);
38
+ const warnings = [];
39
+ const asPubkey = args.asPubkey?.trim();
40
+ let agentId;
41
+ if (asPubkey) {
42
+ agentId = `${asPubkey}:${alias}`;
43
+ }
44
+ else {
45
+ agentId = alias;
46
+ warnings.push(`widget "${widget.id}": no --as-pubkey given — manifest.agentId is the ` +
47
+ `bare alias "${alias}". Cubby queries need the full "<asPubkey>:${alias}" ` +
48
+ `agentId; pass --as-pubkey to bake it in.`);
49
+ }
50
+ // `WidgetDecl.kind` is a free-form string; only forward it (and its config)
51
+ // when it maps to a runtime kind, so buildWidgetManifest's validateConfig
52
+ // doesn't reject an author's host-specific hint (e.g. "panel").
53
+ let kind;
54
+ let config;
55
+ if (widget.kind !== undefined) {
56
+ if (KNOWN_KINDS.has(widget.kind)) {
57
+ kind = widget.kind;
58
+ config = widget.config;
59
+ }
60
+ else {
61
+ warnings.push(`widget "${widget.id}": kind "${widget.kind}" is not a runtime widget ` +
62
+ `kind (${[...KNOWN_KINDS].join(", ")}); dropping kind/config from the ` +
63
+ `baked manifest (the widget still runs as a custom UI).`);
64
+ }
65
+ }
66
+ const manifest = buildWidgetManifest({
67
+ widgetId: widget.id,
68
+ name: widget.name ?? widget.id,
69
+ agentId,
70
+ ...(widget.cubbyAlias !== undefined ? { cubbyAlias: widget.cubbyAlias } : { cubbyAlias: "" }),
71
+ wallet: {
72
+ appId: args.walletAppId ?? process.env.CEF_WALLET_APP_ID ?? cfg.wallet.appId,
73
+ env: cfg.wallet.env,
74
+ },
75
+ endpoints: {
76
+ vault: cfg.vault,
77
+ gar: cfg.gar,
78
+ marketplace: cfg.marketplace,
79
+ s3GatewayAuthInfo: cfg.s3GatewayAuthInfo,
80
+ rpc: cfg.rpc,
81
+ },
82
+ ...(widget.queries && widget.queries.length > 0 ? { queries: widget.queries } : {}),
83
+ ...(widget.events && widget.events.length > 0
84
+ ? { events: widget.events.map((type) => ({ type })) }
85
+ : {}),
86
+ ...(kind !== undefined ? { kind } : {}),
87
+ ...(config !== undefined ? { config } : {}),
88
+ });
89
+ return { manifest, env, warnings };
90
+ }
91
+ //# sourceMappingURL=widget-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-manifest.js","sourceRoot":"","sources":["../../src/lib/widget-manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const WIDGET_RUNTIME_BUNDLE_BASENAME = "widget-runtime.js";
2
+ /**
3
+ * Absolute path to `@cef-ai/widget-runtime/dist/widget-runtime.js`, or `null`
4
+ * if the package (or its build output) can't be resolved.
5
+ */
6
+ export declare function resolveWidgetRuntimeBundle(): string | null;
7
+ //# sourceMappingURL=widget-runtime-bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-runtime-bundle.d.ts","sourceRoot":"","sources":["../../src/lib/widget-runtime-bundle.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,8BAA8B,sBAAsB,CAAC;AAElE;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,GAAG,IAAI,CAY1D"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Locate the built `@cef-ai/widget-runtime` IIFE bundle
3
+ * (`dist/widget-runtime.js`) that `cef build` vendors into each widget's dist
4
+ * dir and `cef dev` serves at `/widget-runtime.js`.
5
+ *
6
+ * The package's `.` export resolves to `dist/index.js`; the IIFE sits next to
7
+ * it as `dist/widget-runtime.js`. Resolving through `createRequire` keeps this
8
+ * working both in the monorepo (workspace symlink) and in a published install
9
+ * (real dependency).
10
+ */
11
+ import { createRequire } from "node:module";
12
+ import fs from "node:fs";
13
+ import path from "node:path";
14
+ const require = createRequire(import.meta.url);
15
+ export const WIDGET_RUNTIME_BUNDLE_BASENAME = "widget-runtime.js";
16
+ /**
17
+ * Absolute path to `@cef-ai/widget-runtime/dist/widget-runtime.js`, or `null`
18
+ * if the package (or its build output) can't be resolved.
19
+ */
20
+ export function resolveWidgetRuntimeBundle() {
21
+ let mainEntry;
22
+ try {
23
+ mainEntry = require.resolve("@cef-ai/widget-runtime");
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ const bundle = path.join(path.dirname(mainEntry), WIDGET_RUNTIME_BUNDLE_BASENAME);
29
+ return fs.existsSync(bundle) ? bundle : null;
30
+ }
31
+ //# sourceMappingURL=widget-runtime-bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-runtime-bundle.js","sourceRoot":"","sources":["../../src/lib/widget-runtime-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,8BAA8B,GAAG,mBAAmB,CAAC;AAElE;;;GAGG;AACH,MAAM,UAAU,0BAA0B;IACxC,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CACtB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EACvB,8BAA8B,CAC/B,CAAC;IACF,OAAO,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC"}
package/dist/lib.d.ts CHANGED
@@ -7,6 +7,10 @@ export { cefInit, detectPackageManager } from "./commands/init.js";
7
7
  export type { CefInitOptions, CefInitResult, PackageManager, } from "./commands/init.js";
8
8
  export { cefBuild } from "./commands/build.js";
9
9
  export type { CefBuildOptions, CefBuildResult } from "./commands/build.js";
10
+ export { cefDev } from "./commands/dev.js";
11
+ export type { CefDevOptions, CefDevHandle } from "./commands/dev.js";
12
+ export { buildWidgetManifestForDecl } from "./lib/widget-manifest.js";
13
+ export type { BuildWidgetManifestArgs, BuildWidgetManifestOutput, } from "./lib/widget-manifest.js";
10
14
  export { cefTypegen } from "./commands/typegen.js";
11
15
  export type { CefTypegenOptions, CefTypegenResult, } from "./commands/typegen.js";
12
16
  export { cefInspect } from "./commands/inspect.js";
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACnE,YAAY,EACV,cAAc,EACd,aAAa,EACb,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EACV,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEjF,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EACV,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EACV,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACnE,YAAY,EACV,cAAc,EACd,aAAa,EACb,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,YAAY,EACV,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EACV,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEjF,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EACV,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EACV,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC"}
package/dist/lib.js CHANGED
@@ -5,6 +5,8 @@
5
5
  */
6
6
  export { cefInit, detectPackageManager } from "./commands/init.js";
7
7
  export { cefBuild } from "./commands/build.js";
8
+ export { cefDev } from "./commands/dev.js";
9
+ export { buildWidgetManifestForDecl } from "./lib/widget-manifest.js";
8
10
  export { cefTypegen } from "./commands/typegen.js";
9
11
  export { cefInspect } from "./commands/inspect.js";
10
12
  export { cefPublish } from "./commands/publish.js";
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAOnE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAMnD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAMnD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM3D,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAOnE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAMtE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAMnD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAMnD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM3D,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cef-ai/cli",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -21,8 +21,9 @@
21
21
  "esbuild": "^0.21.0",
22
22
  "json-schema-to-typescript": "^14.0.0",
23
23
  "typescript": "^5.4.0",
24
- "@cef-ai/agent-sdk": "1.4.0",
25
- "@cef-ai/transport": "1.0.0"
24
+ "@cef-ai/agent-sdk": "2.0.0",
25
+ "@cef-ai/transport": "1.0.0",
26
+ "@cef-ai/widget-runtime": "0.2.0"
26
27
  },
27
28
  "optionalDependencies": {
28
29
  "@cere-ddc-sdk/ddc-client": "^2.16.1"
@@ -4,21 +4,56 @@ export default defineAgent({
4
4
  id: "{{agentId}}",
5
5
  version: "0.1.0",
6
6
  entry: "./src/agent.ts",
7
+ // Terminate an idle Job after 30s (default is "30m"). Fine for a test agent;
8
+ // raise it for long-lived / real-time agents.
9
+ idleTimeout: "30s",
7
10
  card: {
8
11
  name: "{{agentId}}",
9
12
  description: "A hello-world CEF agent scaffolded by `cef init`.",
10
13
  },
11
14
  // One cubby (SQLite) for durable per-stream state.
12
15
  cubbies: [{ alias: "history", migrations: "./migrations/history" }],
13
- // One self-contained widget shipped with the agent.
16
+ // One self-contained widget shipped with the agent. `cef dev` serves it
17
+ // locally (browser wallet connect → queries your dev vault); `cef build`
18
+ // bakes the manifest + runtime so the pushed widget works standalone too.
14
19
  widgets: [
15
20
  {
16
21
  id: "hello",
17
22
  name: "Hello",
18
- description: "Minimal hello-world widget.",
23
+ description: "Lists recent messages from the history cubby.",
19
24
  cubbyAlias: "history",
25
+ // A "list" widget. The named query below reads the cubby; `app.js` calls
26
+ // `window.WidgetRuntime.query("recent")` and renders the rows.
27
+ kind: "list",
28
+ queries: [
29
+ {
30
+ id: "recent",
31
+ label: "Recent messages",
32
+ sql: "SELECT text, ts FROM messages ORDER BY ts DESC LIMIT 20",
33
+ },
34
+ ],
20
35
  dir: "./widgets/hello",
21
- entry: "hello.html",
36
+ // index.html so the CDN serves it at the widget's directory URL
37
+ // (…/widgets/hello) without naming the file.
38
+ entry: "index.html",
22
39
  },
23
40
  ],
41
+ // Schemas for events this agent owns (handled + published). `cef build` folds
42
+ // these into the manifest so the platform and any peer agent that imports
43
+ // this one get the event contract. (Note: `cef typegen` currently types only
44
+ // *peer* events locally — it does not yet type your own events from these.)
45
+ eventSchemas: {
46
+ user_message: {
47
+ type: "object",
48
+ properties: { text: { type: "string" } },
49
+ required: ["text"],
50
+ additionalProperties: false,
51
+ },
52
+ reply: {
53
+ type: "object",
54
+ properties: { text: { type: "string" } },
55
+ required: ["text"],
56
+ additionalProperties: false,
57
+ },
58
+ },
24
59
  });
@@ -4,6 +4,7 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
7
+ "dev": "cef dev",
7
8
  "build": "cef build",
8
9
  "typegen": "cef typegen",
9
10
  "test": "vitest run",
@@ -19,5 +20,10 @@
19
20
  "@cef-ai/testing": "^1.1.9",
20
21
  "typescript": "^5.4.0",
21
22
  "vitest": "^1.5.0"
23
+ },
24
+ "pnpm": {
25
+ "onlyBuiltDependencies": [
26
+ "better-sqlite3"
27
+ ]
22
28
  }
23
29
  }
@@ -25,16 +25,34 @@ export default class HelloAgent {
25
25
 
26
26
  @OnEvent("user_message")
27
27
  async onMessage(event: Event<UserMessage>, ctx: Context) {
28
- await ctx
29
- .cubby("history")
30
- .exec("INSERT INTO messages(id, text, ts) VALUES (?, ?, ?)", [
31
- Date.now(),
32
- event.payload.text,
33
- event.ts,
34
- ]);
35
- await ctx.publish("reply", {
36
- text: `hello — you said: ${event.payload.text}`,
37
- });
28
+ // Never assume a well-formed event. A missing/empty payload must NOT throw
29
+ // — an unhandled error in a handler can leave the Job stuck. Guard first.
30
+ const text =
31
+ typeof event.payload?.text === "string" ? event.payload.text.trim() : "";
32
+ if (!text) {
33
+ await ctx.publish("reply", { text: 'no text received — send { "text": "..." }' });
34
+ return;
35
+ }
36
+
37
+ try {
38
+ // Record time = now. (The runtime hands handlers the published event
39
+ // verbatim — it carries an ISO `timestamp` string, not the `ts: number`
40
+ // the SDK `Event` type currently claims — so `event.ts` is undefined;
41
+ // don't bind a missing value into the NOT NULL `ts` column.)
42
+ const now = Date.now();
43
+ await ctx
44
+ .cubby("history")
45
+ .exec("INSERT INTO messages(id, text, ts) VALUES (?, ?, ?)", [
46
+ now,
47
+ text,
48
+ now,
49
+ ]);
50
+ } catch (err) {
51
+ // A storage hiccup shouldn't crash the handler; log and still reply.
52
+ console.error("failed to persist message", err);
53
+ }
54
+
55
+ await ctx.publish("reply", { text: `hello — you said: ${text}` });
38
56
  }
39
57
 
40
58
  @OnClose
@@ -25,4 +25,17 @@ describe("hello-world agent", () => {
25
25
  .query<{ text: string }>("SELECT text FROM messages");
26
26
  expect(rows.map((r) => r.text)).toEqual(["hi"]);
27
27
  });
28
+
29
+ it("handles an empty payload without throwing or persisting", async () => {
30
+ h = testAgent(HelloAgent, {
31
+ cubbies: [{ alias: "history", migrations: HISTORY_MIGRATIONS }],
32
+ });
33
+ // An event with no `text` must not crash the handler.
34
+ const events = await h.dispatch({ type: "user_message", payload: {} });
35
+ expect(events.map((e) => e.type)).toContain("reply");
36
+ const rows = await h
37
+ .cubby("history")
38
+ .query<{ text: string }>("SELECT text FROM messages");
39
+ expect(rows).toEqual([]); // nothing persisted for an empty payload
40
+ });
28
41
  });
@@ -3,7 +3,7 @@
3
3
  "target": "ES2022",
4
4
  "module": "NodeNext",
5
5
  "moduleResolution": "NodeNext",
6
- "lib": ["ES2022"],
6
+ "lib": ["ES2022", "WebWorker"],
7
7
  "strict": true,
8
8
  "esModuleInterop": true,
9
9
  "skipLibCheck": true,
@@ -1,8 +1,118 @@
1
- // A minimal, self-contained widget (plain HTML + JS — no build step).
1
+ // A real, self-contained widget (plain HTML + JS — no build step).
2
2
  //
3
- // When the @cef-ai/widget-runtime ships, you can read this agent's cubby
4
- // and publish events from here, e.g.:
5
- // const { rows } = await window.WidgetRuntime.query("SELECT text FROM messages");
6
- // await window.WidgetRuntime.publish("user_message", { text: "hi" });
7
- document.getElementById("root").textContent =
8
- "hello from {{agentId}} — this is your widget";
3
+ // It reads this agent's `history` cubby through the injected
4
+ // `window.WidgetRuntime` and renders the rows. `window.WidgetRuntime` is
5
+ // provided by `@cef-ai/widget-runtime`, whose <script> + manifest are baked
6
+ // into the page head by `cef dev` (local) and `cef build` (production).
7
+ //
8
+ // Run it locally with: cef dev
9
+ // → opens a URL; connect your Cere wallet in the browser; the widget then
10
+ // queries your dev vault. Publish messages (e.g. via the agent) and refresh.
11
+
12
+ (function () {
13
+ var app = document.getElementById("app");
14
+
15
+ function el(tag, attrs, text) {
16
+ var node = document.createElement(tag);
17
+ if (attrs) for (var k in attrs) node.setAttribute(k, attrs[k]);
18
+ if (text != null) node.textContent = text;
19
+ return node;
20
+ }
21
+
22
+ function clear() {
23
+ while (app.firstChild) app.removeChild(app.firstChild);
24
+ }
25
+
26
+ function fmtTime(ts) {
27
+ var n = Number(ts);
28
+ if (!isFinite(n)) return String(ts);
29
+ // Rows store epoch millis; fall back gracefully for seconds.
30
+ var d = new Date(n < 1e12 ? n * 1000 : n);
31
+ return isNaN(d.getTime()) ? String(ts) : d.toLocaleString();
32
+ }
33
+
34
+ function renderHeader() {
35
+ app.appendChild(el("h1", null, "{{agentId}}"));
36
+ app.appendChild(el("p", { class: "sub" }, "Recent messages from the history cubby"));
37
+ }
38
+
39
+ function renderRefresh() {
40
+ var btn = el("button", null, "Refresh");
41
+ btn.addEventListener("click", function () {
42
+ btn.disabled = true;
43
+ btn.textContent = "Refreshing…";
44
+ load(); // re-runs the "recent" query; load() re-renders (button included)
45
+ });
46
+ app.appendChild(btn);
47
+ }
48
+
49
+ function renderRows(result) {
50
+ clear();
51
+ renderHeader();
52
+ renderRefresh();
53
+ var cols = result.columns || [];
54
+ var textIdx = cols.indexOf("text");
55
+ var tsIdx = cols.indexOf("ts");
56
+ var rows = result.rows || [];
57
+ if (rows.length === 0) {
58
+ app.appendChild(el("p", { class: "muted" }, "No messages yet."));
59
+ return;
60
+ }
61
+ var ul = el("ul");
62
+ rows.forEach(function (row) {
63
+ var li = el("li");
64
+ li.appendChild(el("div", null, textIdx >= 0 ? String(row[textIdx]) : JSON.stringify(row)));
65
+ if (tsIdx >= 0) li.appendChild(el("div", { class: "time" }, fmtTime(row[tsIdx])));
66
+ ul.appendChild(li);
67
+ });
68
+ app.appendChild(ul);
69
+ }
70
+
71
+ function renderConnect() {
72
+ clear();
73
+ renderHeader();
74
+ app.appendChild(el("p", { class: "muted" }, "Connect your account to load your messages."));
75
+ var btn = el("button", null, "Connect");
76
+ btn.addEventListener("click", function () {
77
+ btn.disabled = true;
78
+ btn.textContent = "Connecting…";
79
+ window.WidgetRuntime
80
+ .connectAgent()
81
+ .then(load)
82
+ .catch(function (err) {
83
+ btn.disabled = false;
84
+ btn.textContent = "Connect";
85
+ renderError(err);
86
+ });
87
+ });
88
+ app.appendChild(btn);
89
+ }
90
+
91
+ function renderError(err) {
92
+ clear();
93
+ renderHeader();
94
+ app.appendChild(el("p", { class: "error" }, "Error: " + (err && err.message ? err.message : String(err))));
95
+ }
96
+
97
+ function load() {
98
+ if (!window.WidgetRuntime) {
99
+ renderError(new Error("WidgetRuntime unavailable — open this widget via `cef dev` or the CDN link."));
100
+ return;
101
+ }
102
+ window.WidgetRuntime
103
+ .query("recent")
104
+ .then(renderRows)
105
+ .catch(function (err) {
106
+ // The cubby throws AgentNotConnectedError until the user connects the
107
+ // agent to their vault. Offer a Connect button in that case.
108
+ if (err && err.name === "AgentNotConnectedError") renderConnect();
109
+ else renderError(err);
110
+ });
111
+ }
112
+
113
+ if (document.readyState === "loading") {
114
+ document.addEventListener("DOMContentLoaded", load, { once: true });
115
+ } else {
116
+ load();
117
+ }
118
+ })();
@@ -0,0 +1,20 @@
1
+ <!doctype html>
2
+ <meta charset="utf-8" />
3
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
4
+ <title>Hello — {{agentId}}</title>
5
+ <style>
6
+ body { font: 15px/1.5 system-ui, sans-serif; margin: 0; padding: 24px; color: #111; background: #fafafa; }
7
+ h1 { font-size: 18px; margin: 0 0 4px; }
8
+ .sub { color: #666; margin: 0 0 16px; }
9
+ ul { list-style: none; padding: 0; margin: 0; }
10
+ li { padding: 10px 12px; background: #fff; border: 1px solid #eee; border-radius: 8px; margin-bottom: 8px; }
11
+ .time { color: #888; font-size: 12px; }
12
+ button { font: inherit; padding: 8px 14px; border-radius: 8px; border: 1px solid #ccc; background: #fff; cursor: pointer; }
13
+ .muted { color: #888; }
14
+ .error { color: #b00020; }
15
+ </style>
16
+ <div id="app">Loading…</div>
17
+ <!-- The @cef-ai/widget-runtime <script> + window.WidgetSandbox manifest are
18
+ injected into <head> by `cef dev` / `cef build`, so window.WidgetRuntime is
19
+ ready by the time app.js runs. -->
20
+ <script src="./app.js"></script>
@@ -1,5 +0,0 @@
1
- <!doctype html>
2
- <meta charset="utf-8" />
3
- <title>Hello — {{agentId}}</title>
4
- <div id="root"></div>
5
- <script src="./app.js"></script>