@cef-ai/cli 0.2.7 → 0.3.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 (127) hide show
  1. package/README.md +75 -1247
  2. package/dist/build/duration.d.ts +22 -0
  3. package/dist/build/duration.d.ts.map +1 -0
  4. package/dist/build/duration.js +44 -0
  5. package/dist/build/duration.js.map +1 -0
  6. package/dist/build/esbuild-plugin.d.ts +32 -0
  7. package/dist/build/esbuild-plugin.d.ts.map +1 -0
  8. package/dist/build/esbuild-plugin.js +53 -0
  9. package/dist/build/esbuild-plugin.js.map +1 -0
  10. package/dist/build/lints.d.ts +55 -0
  11. package/dist/build/lints.d.ts.map +1 -0
  12. package/dist/build/lints.js +214 -0
  13. package/dist/build/lints.js.map +1 -0
  14. package/dist/build/load-config.d.ts +114 -0
  15. package/dist/build/load-config.d.ts.map +1 -0
  16. package/dist/build/load-config.js +150 -0
  17. package/dist/build/load-config.js.map +1 -0
  18. package/dist/build/manifest.d.ts +156 -0
  19. package/dist/build/manifest.d.ts.map +1 -0
  20. package/dist/build/manifest.js +111 -0
  21. package/dist/build/manifest.js.map +1 -0
  22. package/dist/build/targeting.d.ts +15 -0
  23. package/dist/build/targeting.d.ts.map +1 -0
  24. package/dist/build/targeting.js +69 -0
  25. package/dist/build/targeting.js.map +1 -0
  26. package/dist/cli.d.ts +2 -2
  27. package/dist/cli.d.ts.map +1 -0
  28. package/dist/cli.js +107 -62
  29. package/dist/cli.js.map +1 -0
  30. package/dist/commands/build.d.ts +41 -0
  31. package/dist/commands/build.d.ts.map +1 -0
  32. package/dist/commands/build.js +252 -0
  33. package/dist/commands/build.js.map +1 -0
  34. package/dist/commands/inspect.d.ts +49 -0
  35. package/dist/commands/inspect.d.ts.map +1 -0
  36. package/dist/commands/inspect.js +135 -0
  37. package/dist/commands/inspect.js.map +1 -0
  38. package/dist/commands/typegen.d.ts +36 -0
  39. package/dist/commands/typegen.d.ts.map +1 -0
  40. package/dist/commands/typegen.js +210 -0
  41. package/dist/commands/typegen.js.map +1 -0
  42. package/dist/index.d.ts +6 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +6 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/lib.d.ts +12 -0
  47. package/dist/lib.d.ts.map +1 -0
  48. package/dist/lib.js +9 -0
  49. package/dist/lib.js.map +1 -0
  50. package/dist/typegen/augment.d.ts +57 -0
  51. package/dist/typegen/augment.d.ts.map +1 -0
  52. package/dist/typegen/augment.js +87 -0
  53. package/dist/typegen/augment.js.map +1 -0
  54. package/dist/typegen/fetch.d.ts +30 -0
  55. package/dist/typegen/fetch.d.ts.map +1 -0
  56. package/dist/typegen/fetch.js +38 -0
  57. package/dist/typegen/fetch.js.map +1 -0
  58. package/dist/typegen/lockfile.d.ts +42 -0
  59. package/dist/typegen/lockfile.d.ts.map +1 -0
  60. package/dist/typegen/lockfile.js +58 -0
  61. package/dist/typegen/lockfile.js.map +1 -0
  62. package/dist/typegen/schema-to-ts.d.ts +21 -0
  63. package/dist/typegen/schema-to-ts.d.ts.map +1 -0
  64. package/dist/typegen/schema-to-ts.js +29 -0
  65. package/dist/typegen/schema-to-ts.js.map +1 -0
  66. package/package.json +20 -58
  67. package/dist/commands/auth/index.d.ts +0 -2
  68. package/dist/commands/auth/index.js +0 -162
  69. package/dist/commands/deploy/clone.d.ts +0 -13
  70. package/dist/commands/deploy/clone.js +0 -143
  71. package/dist/commands/deploy/delete.d.ts +0 -14
  72. package/dist/commands/deploy/delete.js +0 -134
  73. package/dist/commands/deploy/deploy.d.ts +0 -24
  74. package/dist/commands/deploy/deploy.js +0 -654
  75. package/dist/commands/deploy/index.d.ts +0 -2
  76. package/dist/commands/deploy/index.js +0 -216
  77. package/dist/commands/deploy/status.d.ts +0 -14
  78. package/dist/commands/deploy/status.js +0 -61
  79. package/dist/commands/dev/index.d.ts +0 -2
  80. package/dist/commands/dev/index.js +0 -134
  81. package/dist/commands/dev/server.d.ts +0 -14
  82. package/dist/commands/dev/server.js +0 -195
  83. package/dist/commands/dev/static/app.js +0 -633
  84. package/dist/commands/dev/static/index.html +0 -205
  85. package/dist/commands/dev/static/static/app.js +0 -633
  86. package/dist/commands/dev/static/static/index.html +0 -205
  87. package/dist/commands/dev/static/static/style.css +0 -184
  88. package/dist/commands/dev/static/style.css +0 -184
  89. package/dist/commands/playground/index.d.ts +0 -2
  90. package/dist/commands/playground/index.js +0 -75
  91. package/dist/commands/playground/test.d.ts +0 -15
  92. package/dist/commands/playground/test.js +0 -166
  93. package/dist/commands/service/index.d.ts +0 -2
  94. package/dist/commands/service/index.js +0 -89
  95. package/dist/lib/api.d.ts +0 -146
  96. package/dist/lib/api.js +0 -330
  97. package/dist/lib/config.d.ts +0 -12
  98. package/dist/lib/config.js +0 -145
  99. package/dist/lib/credentials.d.ts +0 -19
  100. package/dist/lib/credentials.js +0 -68
  101. package/dist/lib/runtime/agent-router.d.ts +0 -12
  102. package/dist/lib/runtime/agent-router.js +0 -67
  103. package/dist/lib/runtime/context-builder.d.ts +0 -27
  104. package/dist/lib/runtime/context-builder.js +0 -166
  105. package/dist/lib/runtime/cubby-manager.d.ts +0 -20
  106. package/dist/lib/runtime/cubby-manager.js +0 -162
  107. package/dist/lib/runtime/index.d.ts +0 -51
  108. package/dist/lib/runtime/index.js +0 -181
  109. package/dist/lib/runtime/log-collector.d.ts +0 -17
  110. package/dist/lib/runtime/log-collector.js +0 -61
  111. package/dist/lib/runtime/stream-manager.d.ts +0 -10
  112. package/dist/lib/runtime/stream-manager.js +0 -77
  113. package/dist/lib/runtime/types.d.ts +0 -76
  114. package/dist/lib/runtime/types.js +0 -2
  115. package/dist/lib/transpile.d.ts +0 -1
  116. package/dist/lib/transpile.js +0 -9
  117. package/dist/lib/typecheck.d.ts +0 -31
  118. package/dist/lib/typecheck.js +0 -175
  119. package/dist/lib/types.d.ts +0 -246
  120. package/dist/lib/types.js +0 -2
  121. package/dist/lib/utils.d.ts +0 -4
  122. package/dist/lib/utils.js +0 -33
  123. package/example/.env.example +0 -6
  124. package/example/agents/object-detection/tasks/yolo.ts +0 -28
  125. package/example/agents/parking-violation-detector/tasks/detect.ts +0 -326
  126. package/example/cef.config.yaml +0 -91
  127. package/example/engagements/engagement.ts +0 -902
package/README.md CHANGED
@@ -1,1280 +1,108 @@
1
- # CEF AI CLI
1
+ # @cef-ai/cli
2
2
 
3
- Build, test, and deploy CEF AI agent topologies from the command line.
3
+ `cef` — build, typegen, and inspect agents from the command line. Mirrors
4
+ the runtime contract: bundles emit `globalThis.__cefAgent`, manifests
5
+ carry the routing table the runtime reads.
4
6
 
5
- Write agent handlers locally, test them with a real dev server (SQLite cubbies, streams, execution tracing), then deploy to the platform from a single YAML config.
6
-
7
- **Package:** `@cef-ai/cli` v0.2.0
8
- **Binaries:** `cef`, `cef-deploy`
9
- **Requirements:** Node.js 18+
10
-
11
- ---
12
-
13
- ## Table of Contents
14
-
15
- - [Quick Start](#quick-start)
16
- - [Developer Workflow](#developer-workflow)
17
- - [Commands](#commands)
18
- - [cef dev - Local Development Server](#cef-dev---local-development-server)
19
- - [Dev UI](#dev-ui)
20
- - [HTTP API Endpoints](#http-api-endpoints)
21
- - [WebSocket API](#websocket-api)
22
- - [Data Directory (.cef-dev/)](#data-directory-cef-dev)
23
- - [Hot Reload](#hot-reload)
24
- - [cef deploy - Deploy Topology](#cef-deploy---deploy-topology)
25
- - [Deploy Order](#deploy-order)
26
- - [ID Writeback](#id-writeback)
27
- - [Stale ID Detection](#stale-id-detection)
28
- - [Dry Run](#dry-run)
29
- - [Partial Deploy](#partial-deploy)
30
- - [cef deploy status - Compare Local vs Deployed](#cef-deploy-status---compare-local-vs-deployed)
31
- - [cef deploy clone - Download Existing Service](#cef-deploy-clone---download-existing-service)
32
- - [cef deploy delete - Delete Deployed Entities](#cef-deploy-delete---delete-deployed-entities)
33
- - [cef service list - List Agent Services](#cef-service-list---list-agent-services)
34
- - [cef service create - Create New Agent Service](#cef-service-create---create-new-agent-service)
35
- - [cef playground test - Test Agent Tools via MCP](#cef-playground-test---test-agent-tools-via-mcp)
36
- - [Single Test](#single-test)
37
- - [List Tools](#list-tools)
38
- - [Batch Tests](#batch-tests)
39
- - [Test File Format (cef.tests.yaml)](#test-file-format-ceftestsyaml)
40
- - [Configuration (cef.config.yaml)](#configuration-cefconfigyaml)
41
- - [Top-Level Fields](#top-level-fields)
42
- - [Engagements](#engagements)
43
- - [Agents](#agents)
44
- - [Cubbies](#cubbies)
45
- - [Workspaces](#workspaces)
46
- - [Full Example Config](#full-example-config)
47
- - [Agent Sandbox](#agent-sandbox)
48
- - [Handler Signature](#handler-signature)
49
- - [Available Globals](#available-globals)
50
- - [Restrictions](#restrictions)
51
- - [Context API Reference](#context-api-reference)
52
- - [Logging](#logging)
53
- - [Event Emission](#event-emission)
54
- - [HTTP Fetch](#http-fetch)
55
- - [Agent-to-Agent Calls](#agent-to-agent-calls)
56
- - [Cubby Operations](#cubby-operations)
57
- - [Stream Subscriptions](#stream-subscriptions)
58
- - [Raft Queries](#raft-queries)
59
- - [Environment Variables](#environment-variables)
60
- - [Options Reference](#options-reference)
61
- - [Examples](#examples)
62
- - [Hello World](#hello-world)
63
- - [Drone Telemetry (Workspaces + Streams)](#drone-telemetry-workspaces--streams)
64
- - [Wiki Knowledge Graph (Graph Viz + Batch)](#wiki-knowledge-graph-graph-viz--batch)
65
- - [Testing](#testing)
66
- - [Troubleshooting](#troubleshooting)
67
-
68
- ---
69
-
70
- ## Quick Start
71
-
72
- ```bash
73
- # Install globally
74
- npm install -g @cef-ai/cli
75
-
76
- # Or use npx
77
- npx @cef-ai/cli dev
78
-
79
- # Start local dev server (no auth needed)
80
- cef dev
81
-
82
- # Start with a specific config
83
- cef dev --config ./my-agent/cef.config.yaml
84
-
85
- # Authenticate (opens browser)
86
- cef login
87
-
88
- # Deploy to platform
89
- cef deploy --config ./cef.config.yaml
90
- ```
91
-
92
- ---
93
-
94
- ## Developer Workflow
95
-
96
- The recommended flow from idea to production:
97
-
98
- ```
99
- 1. Scaffold cef service create --name my-agent
100
- Set up cef.config.yaml with agents, cubbies, engagements
101
-
102
- 2. Write agents Create handler .ts files (fully inline, no imports)
103
- Define cubby migrations in config for any SQL state
104
-
105
- 3. Dev server cef dev
106
- Opens http://localhost:8787 with:
107
- - Topology sidebar, agent/engagement panels
108
- - Stream push (single, bulk, file upload)
109
- - Live execution logs and call chain tracing
110
-
111
- 4. Test agents POST /api/agents/:alias/:task with payloads
112
- Trigger full engagements via POST /api/trigger
113
- Push stream packets via POST /api/streams/:id/push
114
-
115
- 5. Inspect data Use the SQL editor in the dev UI
116
- Or: POST /api/cubbies/:alias/query with {"sql": "SELECT ..."}
117
- Cubbies are real SQLite with vector support (sqlite-vec)
118
-
119
- 6. Iterate Edit agent code; changes hot-reload automatically
120
- .cef-dev/ is cleared on shutdown (use --persist to keep)
121
-
122
- 7. Deploy cef login (browser-based auth, one-time)
123
- cef deploy
124
- IDs are written back into cef.config.yaml
125
-
126
- 8. Verify cef deploy status (compares local vs deployed)
127
- Redeploy after changes: cef deploy
128
- ```
129
-
130
- ---
131
-
132
- ## Commands
133
-
134
- | Command | Description | Auth Required |
135
- |-|-|-|
136
- | `cef login` | Authenticate via browser (saves token to `~/.cef/credentials.json`) | No |
137
- | `cef logout` | Clear stored credentials | No |
138
- | `cef whoami` | Show current authentication status | No |
139
- | `cef dev` | Start local dev server with UI, hot-reload, real SQLite cubbies | No |
140
- | `cef deploy` | Deploy topology to orchestrator from cef.config.yaml | Yes |
141
- | `cef deploy status` | Compare local config vs deployed state | Yes |
142
- | `cef deploy clone` | Download an existing service into a directory | Yes |
143
- | `cef deploy delete` | Delete deployed entities (reverse dependency order) | Yes |
144
- | `cef service list` | List agent services from ROB | Yes |
145
- | `cef service create` | Create a new agent service on ROB + orchestrator | Yes |
146
- | `cef playground test` | Run playground tests against deployed agent tools | Yes |
147
-
148
- ---
149
-
150
- ### cef dev - Local Development Server
151
-
152
- Starts a local dev server that emulates the CEF platform. Loads `cef.config.yaml`, runs agent code in sandboxed V8 contexts, and provides an HTTP API and web UI.
153
-
154
- No auth token or orchestrator connection required. Runs as a persistent process until Ctrl+C.
155
-
156
- ```bash
157
- cef dev # Default: localhost:8787
158
- cef dev --config ./my-agent/cef.config.yaml
159
- cef dev --port 3000
160
- cef dev --host 0.0.0.0
161
- cef dev --persist # Keep .cef-dev/ data after shutdown
162
- ```
163
-
164
- | Option | Default | Description |
165
- |-|-|-|
166
- | `--config <path>` | `./cef.config.yaml` | Path to config file |
167
- | `--port <port>` | `8787` | Server port |
168
- | `--host <host>` | `localhost` | Server host |
169
- | `--persist` | `false` | Keep `.cef-dev/` data after shutdown |
170
-
171
- #### Dev UI
172
-
173
- Open `http://localhost:<port>` to access the built-in web UI:
174
-
175
- - **Topology sidebar** listing all engagements, agents, cubbies, and workspaces
176
- - **Engagement trigger panel** with payload editor and stream push (single, bulk JSON Lines, file upload for .json/.jsonl)
177
- - **Engagement blast mode** with repeat count, delay, and JSON file upload for burst testing
178
- - **Agent task panels** with pre-filled payloads based on `parameters` JSON Schema from config
179
- - **Run Batch** button on agent panels; queries a cubby for input rows via `batch_file` SQL, then calls the agent once per row
180
- - **Cubby table browser** with SQL editor for ad-hoc queries
181
- - **Saved queries** for the SQL editor; save, load, and delete named queries from a dropdown
182
- - **Graph visualization** tab on cubby panels using vis.js; color-coded nodes by type (artifact, work, operator, eval), click-to-inspect detail panel, legend, and stats
183
- - **Live execution logs** with filtering by execution ID
184
- - **Call chain tracing** visualizing engagement -> agent -> cubby execution flows
185
- - **Real-time updates** via WebSocket
186
-
187
- **Config hint:** Add `parameters` and `returns` to agent tasks in cef.config.yaml (JSON Schema format). The dev UI uses these to pre-fill payloads and show schema hints. These fields are local-only and not sent to the orchestrator.
188
-
189
- #### HTTP API Endpoints
190
-
191
- All endpoints are available for scripting with curl or any HTTP client.
192
-
193
- | Method | Path | Body | Description |
194
- |-|-|-|-|
195
- | `GET` | `/` | - | Dev UI |
196
- | `GET` | `/api/topology` | - | Returns loaded agents, engagements, cubbies, workspaces |
197
- | `GET` | `/api/executions` | - | Returns execution logs (optional `?executionId=` filter) |
198
- | `POST` | `/api/trigger` | `{"engagement": "Name", "payload": {...}}` | Start an engagement |
199
- | `POST` | `/api/agents/:alias/:task` | `{"payload": {...}}` | Call an agent task directly |
200
- | `POST` | `/api/streams/:id/push` | `{"data": {"sequenceNum": 0, "payload": {...}}}` | Push a packet to a running stream |
201
- | `POST` | `/api/cubbies/:alias/query` | `{"sql": "SELECT ...", "params": [], "instanceId": "default"}` | SQL read query |
202
- | `POST` | `/api/cubbies/:alias/exec` | `{"sql": "INSERT ...", "params": []}` | SQL write operation |
203
- | `GET` | `/api/cubbies/:alias/instances` | - | List all cubby instances |
204
-
205
- Example: call an agent task directly:
206
-
207
- ```bash
208
- curl -X POST http://localhost:8787/api/agents/greeter/greet \
209
- -H "Content-Type: application/json" \
210
- -d '{"payload": {"name": "Alice"}}'
211
- ```
212
-
213
- Example: query a cubby:
214
-
215
- ```bash
216
- curl -X POST http://localhost:8787/api/cubbies/greetings/query \
217
- -H "Content-Type: application/json" \
218
- -d '{"sql": "SELECT * FROM greetings"}'
219
- ```
220
-
221
- Example: trigger an engagement:
222
-
223
- ```bash
224
- curl -X POST http://localhost:8787/api/trigger \
225
- -H "Content-Type: application/json" \
226
- -d '{"engagement": "Hello World", "payload": {"streamId": "test-stream-1"}}'
227
- ```
228
-
229
- #### WebSocket API
230
-
231
- Connect to `ws://localhost:<port>/ws` for real-time streaming of logs and trace events.
232
-
233
- Messages are JSON with two types:
234
-
235
- **Log entries:**
236
-
237
- ```json
238
- {
239
- "type": "log",
240
- "data": {
241
- "timestamp": 1712345678000,
242
- "executionId": "exec-abc123",
243
- "agentAlias": "greeter",
244
- "taskAlias": "greet",
245
- "level": "log",
246
- "args": ["Greeter agent called with name: Alice"]
247
- }
248
- }
249
- ```
250
-
251
- **Trace events:**
252
-
253
- ```json
254
- {
255
- "type": "trace",
256
- "data": {
257
- "timestamp": 1712345678000,
258
- "executionId": "exec-abc123",
259
- "type": "agent:call",
260
- "caller": "engagement:Hello World",
261
- "callee": "greeter.greet",
262
- "durationMs": 12,
263
- "success": true
264
- }
265
- }
266
- ```
267
-
268
- Trace event types: `engagement:start`, `agent:call`, `agent:return`, `cubby:query`, `cubby:exec`
269
-
270
- #### Data Directory (.cef-dev/)
271
-
272
- The dev server stores SQLite databases in `.cef-dev/cubbies/{alias}/{instanceId}.db` relative to the config directory.
273
-
274
- ```
275
- .cef-dev/
276
- cubbies/
277
- greetings/
278
- default.db
279
- syncMission/
280
- default.db
281
- drone-001.db
282
- ```
283
-
284
- By default, `.cef-dev/` is deleted on shutdown. Use `--persist` to keep data between runs.
285
-
286
- #### Hot Reload
287
-
288
- The dev server watches all agent task and engagement handler files. On save:
289
-
290
- 1. New TypeScript code is read from disk
291
- 2. Code is transpiled (ES2022 target) and cached
292
- 3. Next call to that agent/task uses the updated code
293
- 4. A `[reload] path/to/file` message appears in the console
294
-
295
- In-flight executions continue with the old code; only new calls use the updated version. No server restart needed.
296
-
297
- **What runs locally:**
298
-
299
- - **Agents** execute in sandboxed V8 contexts (see [Agent Sandbox](#agent-sandbox))
300
- - **Cubbies** are real SQLite databases (better-sqlite3 + sqlite-vec for vector ops)
301
- - **Streams** are in-memory async iterators; push packets via UI or API
302
- - **Execution tracing** tracks engagement -> agent -> cubby call chains in real-time
303
-
304
- ---
305
-
306
- ### cef deploy - Deploy Topology
307
-
308
- Reads `cef.config.yaml`, creates or updates each entity on the orchestrator, and writes returned IDs back into the config.
309
-
310
- ```bash
311
- cef deploy
312
- cef deploy --config ./app/cef.config.yaml
313
- cef deploy --dry-run
314
- cef deploy --only agent
315
- ```
316
-
317
- | Option | Default | Description |
318
- |-|-|-|
319
- | `--config <path>` | `./cef.config.yaml` | Path to config file |
320
- | `--dry-run` | `false` | Show planned operations without calling the API |
321
- | `--only <type>` | (all) | Deploy only one entity type |
322
-
323
- Valid `--only` values: `engagement`, `agent`, `cubby`, `workspace`, `stream`, `deployment`, `raft`
324
-
325
- #### Deploy Order
326
-
327
- Entities are created in dependency order:
328
-
329
- ```
330
- Engagements -> Agents -> Cubbies -> Workspaces -> Streams -> Deployments -> Rafts
331
- ```
332
-
333
- Each entity type completes before the next begins. If an entity already has an ID in config, the CLI issues an update instead of a create.
334
-
335
- #### ID Writeback
336
-
337
- After each entity type is created, the returned IDs are written back into `cef.config.yaml`. For example, after creating an engagement:
338
-
339
- ```yaml
340
- engagements:
341
- - name: Hello World
342
- file: ./engagements/hello-engagement.ts
343
- engagementId: eng-2f8b9517 # written by CLI
344
- ```
345
-
346
- If the deploy fails partway through, already-created IDs are preserved in config. Subsequent runs detect existing IDs and issue updates instead of creates. The final `agentServiceId` resolved from ROB is also written back.
347
-
348
- Commit the updated config after a successful deploy.
349
-
350
- #### Stale ID Detection
351
-
352
- If `agentServiceId` in config does not match the resolved service from ROB (e.g. you copied a config from another service and changed `agentServicePubKey`), the CLI warns that IDs may belong to a different service. It prompts to clear all entity IDs and deploy fresh.
353
-
354
- #### Dry Run
355
-
356
- ```bash
357
- cef deploy --dry-run
358
- ```
359
-
360
- Logs what would be created or updated without making any API calls.
361
-
362
- #### Partial Deploy
363
-
364
- Deploy a single entity type:
365
-
366
- ```bash
367
- cef deploy --only agent
368
- cef deploy --only cubby
369
- cef deploy --only workspace
370
- ```
371
-
372
- ---
373
-
374
- ### cef deploy status - Compare Local vs Deployed
375
-
376
- Compares local handler code against the deployed version on the orchestrator. Checks engagements and agents (task code).
377
-
378
- ```bash
379
- cef deploy status
380
- cef deploy status --config ./app/cef.config.yaml
381
- ```
382
-
383
- | Option | Default | Description |
384
- |-|-|-|
385
- | `--config <path>` | `./cef.config.yaml` | Path to config file |
386
-
387
- Status values:
388
-
389
- | Status | Meaning |
390
- |-|-|
391
- | `up-to-date` | Local code matches deployed version byte-for-byte |
392
- | `outdated` | Deployed code differs from local |
393
- | `not-deployed` | Entity has no ID in config (never deployed) |
394
- | `not-found` | Entity ID exists in config but not found on orchestrator |
395
-
396
- Example output:
397
-
398
- ```
399
- [OK] engagement: Hello World (eng-2f8b9517)
400
- [OUTDATED] agent: Object Detection (agent-628677bd)
401
- task: Yolo [OUTDATED]
402
- task: Detect [OK]
403
-
404
- 1 outdated, 0 not deployed.
405
- ```
406
-
407
- For agents, the status is aggregated from all tasks. If any task is outdated, the agent is reported as outdated.
408
-
409
- ---
410
-
411
- ### cef deploy clone - Download Existing Service
412
-
413
- Downloads all code and config from a deployed agent service and writes local files.
414
-
415
- ```bash
416
- cef deploy clone --pubkey 0x... --output-dir ./my-agent
417
- cef deploy clone --pubkey 0x... --output-dir ./my-agent --force
418
- cef deploy clone --config ./other/cef.config.yaml
419
- ```
420
-
421
- | Option | Default | Description |
422
- |-|-|-|
423
- | `--config <path>` | `./cef.config.yaml` | Path to config file |
424
- | `--pubkey <key>` | (from config) | Agent service public key (`0x...`) |
425
- | `--output-dir <dir>` | (config directory) | Directory to write files into |
426
- | `--force` | `false` | Overwrite existing files |
427
-
428
- Downloads in parallel:
429
- - Engagement handler code -> `./engagements/{name}.ts`
430
- - Agent task code -> `./agents/{alias}/tasks/{taskAlias}.ts`
431
- - Full ontology (workspaces, streams, deployments, rafts)
432
- - Cubby configs with migrations
433
-
434
- Produces a complete `cef.config.yaml` with all IDs populated, ready for `cef deploy status` or further edits. Without `--force`, existing files are not overwritten.
435
-
436
- ---
437
-
438
- ### cef deploy delete - Delete Deployed Entities
439
-
440
- Deletes deployed entities in reverse dependency order and removes the corresponding IDs from config.
441
-
442
- ```bash
443
- cef deploy delete
444
- cef deploy delete --only agent
445
- cef deploy delete --force # Skip confirmation prompt
446
- ```
447
-
448
- | Option | Default | Description |
449
- |-|-|-|
450
- | `--config <path>` | `./cef.config.yaml` | Path to config file |
451
- | `--only <type>` | (all) | Delete only one entity type |
452
- | `--force` | `false` | Skip confirmation prompt |
453
-
454
- Deletion order (reverse of deploy):
455
-
456
- ```
457
- Deployments -> Rafts -> Streams -> Workspaces -> Agents -> Engagements
458
- ```
459
-
460
- After successful deletion, the corresponding IDs are cleared from `cef.config.yaml`.
461
-
462
- **Note:** Cubbies cannot be deleted via the CLI. A warning is shown for cubbies with IDs.
463
-
464
- Without `--force`, the CLI lists all entities to be deleted and asks for confirmation. In non-interactive terminals, `--force` is required.
465
-
466
- ---
467
-
468
- ### cef service list - List Agent Services
469
-
470
- Lists all active (non-archived) agent services from ROB.
471
-
472
- ```bash
473
- cef service list
474
- cef service list --config ./app/cef.config.yaml
475
- ```
476
-
477
- | Option | Default | Description |
478
- |-|-|-|
479
- | `--config <path>` | `./cef.config.yaml` | Path to config file |
480
-
481
- Requires `CEF_ROB_API_URL` (defaults to stage URL if not set).
482
-
483
- Output:
484
-
485
- ```
486
- Agent Services (3):
487
- Parking Detection
488
- agentServiceId: 2620
489
- agentServicePubKey: 0x788b3863...
490
- created: 2024-01-15T10:30:00Z
491
-
492
- Hello World Agent
493
- agentServiceId: 2621
494
- agentServicePubKey: 0xbbccddee...
495
- created: 2024-02-01T08:00:00Z
496
- ```
497
-
498
- ---
499
-
500
- ### cef service create - Create New Agent Service
501
-
502
- Creates a new agent service on both ROB and the orchestrator.
503
-
504
- ```bash
505
- cef service create --name my-agent
506
- cef service create --name my-agent --bucket-id 1505
507
- ```
508
-
509
- | Option | Default | Required | Description |
510
- |-|-|-|-|
511
- | `--name <name>` | - | Yes | Name of the new agent service |
512
- | `--config <path>` | `./cef.config.yaml` | No | Path to config file |
513
- | `--bucket-id <id>` | `1` | No | DDC bucket ID |
514
-
515
- Requires `CEF_ROB_API_URL` (defaults to stage URL if not set).
516
-
517
- Returns the service name, `agentServiceId`, and `agentServicePubKey`. Use the pubkey in your `cef.config.yaml`.
518
-
519
- ---
520
-
521
- ### cef playground test - Test Agent Tools via MCP
522
-
523
- Tests deployed agent tools using the MCP (Model Context Protocol) playground API. Agents must have an `agentId` (deployed via `cef deploy`).
524
-
525
- ```bash
526
- cef playground test [options]
527
- ```
528
-
529
- | Option | Default | Description |
530
- |-|-|-|
531
- | `--config <path>` | `./cef.config.yaml` | Path to config file |
532
- | `--agent <name>` | - | Agent name, alias, or agentId |
533
- | `--tool <alias>` | - | Task alias (tool name) to call |
534
- | `--args <json>` | - | JSON arguments to pass to the tool |
535
- | `--test-file <path>` | - | Path to `cef.tests.yaml` for batch testing |
536
- | `--list-tools` | `false` | List available tools on an agent |
537
-
538
- Agent resolution: matches by name, alias, or agentId from config.
539
-
540
- #### Single Test
541
-
542
- ```bash
543
- cef playground test \
544
- --agent objectDetection \
545
- --tool yolo \
546
- --args '{"image": "https://example.com/photo.jpg"}'
547
- ```
548
-
549
- #### List Tools
550
-
551
- ```bash
552
- cef playground test --agent objectDetection --list-tools
553
- ```
554
-
555
- Lists all available task aliases (tools) on the specified agent.
556
-
557
- #### Batch Tests
558
-
559
- ```bash
560
- cef playground test --test-file ./cef.tests.yaml
561
- ```
562
-
563
- Runs all tests defined in the file. Exits with code 1 if any test fails.
564
-
565
- #### Test File Format (cef.tests.yaml)
566
-
567
- ```yaml
568
- tests:
569
- - agent: objectDetection
570
- tool: yolo
571
- arguments:
572
- image: "https://example.com/photo.jpg"
573
- expect:
574
- success: true
575
- result:
576
- totalDetections: 3
577
-
578
- - agent: parkingViolationDetector
579
- tool: detect
580
- arguments:
581
- timestamp: 1712345678
582
- detections: []
583
- telemetry: {}
584
- expect:
585
- success: true
586
- ```
587
-
588
- Expectations use partial matching; the response only needs to contain the specified fields. Omit `expect` to just verify the call succeeds without error.
589
-
590
- Output:
7
+ ## Install
591
8
 
9
+ ```sh
10
+ pnpm add -D @cef-ai/cli
592
11
  ```
593
- [PASS] objectDetection > yolo (123ms)
594
- {"totalDetections": 3, "detections": [...]}
595
- [FAIL] parkingViolationDetector > detect (456ms)
596
- - expected totalDetections: 3, got: 0
597
- [ERROR] someAgent > someTask (789ms)
598
- Agent not found
599
-
600
- Results: 1 passed, 1 failed, 1 error
601
- ```
602
-
603
- ---
604
12
 
605
- ## Configuration (cef.config.yaml)
13
+ This adds the `cef` binary to `node_modules/.bin`. In a workspace project,
14
+ invoke it via `pnpm exec cef <subcommand>`.
606
15
 
607
- The config file defines your entire agent topology. All file paths are resolved relative to the config file location. By default the CLI looks for `./cef.config.yaml` in the current directory.
16
+ ## Subcommands
608
17
 
609
- ### Top-Level Fields
18
+ | Subcommand | Status | Description |
19
+ | --- | --- | --- |
20
+ | `cef build` | shipped | Lint the agent entry, bundle with esbuild (IIFE footer), emit `dist/<agentId>/{bundle.js,manifest.json}`. |
21
+ | `cef typegen` | shipped | Generate `.cef/generated.d.ts` (declaration-merged `KnownEventTypes`) and refresh `cef.lock.json`. |
22
+ | `cef inspect <agentDir>` | shipped | Read a built `manifest.json`, run the bundle in `node:vm`, and report the methods exposed on `__cefAgent` plus any missing routing targets. |
23
+ | `cef test` | stub | Placeholder — use `vitest` directly with `@cef-ai/testing` until the integrated runner lands. |
24
+ | `cef publish` | stub | Placeholder — pending the Marketplace API. |
25
+ | `cef dev` | stub | Placeholder — pending the packaged platform image. |
610
26
 
611
- ```yaml
612
- agentServicePubKey: "0x..." # Required. 64-char hex string with 0x prefix.
613
- agentServiceId: "2620" # Optional. Set by CLI on first deploy.
27
+ `cef build` writes one directory per declared agent:
614
28
 
615
- engagements: [...] # Optional. Engagement definitions.
616
- agents: [...] # Optional. Agent definitions.
617
- cubbies: [...] # Optional. Cubby (database) definitions.
618
- workspaces: [...] # Optional. Workspace/stream/deployment definitions.
619
29
  ```
620
-
621
- Get `agentServicePubKey` from `cef service list` or `cef service create`.
622
-
623
- ### Engagements
624
-
625
- Engagements are the entry points that subscribe to streams and orchestrate agent calls.
626
-
627
- ```yaml
628
- engagements:
629
- - name: Hello World # Required. Display name.
630
- description: Greets incoming events # Optional.
631
- file: ./engagements/hello.ts # Required. Path to handler file.
632
- version: 1.0.0 # Optional. Semantic version.
633
- engagementId: eng-2f8b9517 # Set by CLI on deploy. Do not set manually.
634
- parameters: # Optional. JSON Schema for dev UI hints.
635
- type: object
636
- properties:
637
- streamId:
638
- type: string
639
- required: [streamId]
30
+ dist/
31
+ <agentId>/
32
+ bundle.js # IIFE that assigns an instance to globalThis.__cefAgent
33
+ manifest.json # AgentManifest body (per prototype.md) — bundle is also
34
+ # embedded inline; identity / signature fields are blank
35
+ # until `cef publish` signs and uploads.
640
36
  ```
641
37
 
642
- The `parameters` field is local-only (not sent to orchestrator). It drives input hints in the dev UI.
643
-
644
- ### Agents
38
+ `cef typegen` reads `cef.config.ts` (and `publishes` declarations) and
39
+ writes `.cef/generated.d.ts`, populating `KnownEventTypes` so authors
40
+ get string-literal autocompletion on `@OnEvent` and `ctx.publish`. The
41
+ `cef.lock.json` snapshot is rewritten on every run so VCS diffs surface
42
+ typegen drift.
645
43
 
646
- Agents contain one or more tasks (tools). Each task has its own handler file.
44
+ ## Quickstart
647
45
 
648
- ```yaml
649
- agents:
650
- - name: Object Detection # Required. Display name.
651
- alias: objectDetection # Required. Used in context.agents.{alias}.
652
- description: Runs YOLO detection # Optional.
653
- version: 1.0.0 # Optional.
654
- agentId: agent-628677bd # Set by CLI on deploy. Do not set manually.
655
- tasks:
656
- - name: Yolo # Required. Display name.
657
- alias: yolo # Required. Used in context.agents.{alias}.{taskAlias}().
658
- file: ./agents/od/tasks/yolo.ts # Required. Path to handler file.
659
- parameters: # Optional. JSON Schema for input.
660
- type: object
661
- properties:
662
- image:
663
- type: string
664
- description: URL of image to analyze
665
- required: []
666
- returns: # Optional. JSON Schema for output.
667
- type: object
668
- properties:
669
- totalDetections:
670
- type: number
671
- detections:
672
- type: array
673
- batch_file: ./agents/od/eval.sql # Optional. SQL file for Run Batch (dev only).
674
- batch_cubby: detection_store # Optional. Cubby alias to run batch_file against.
46
+ ```sh
47
+ pnpm add -D @cef-ai/cli
48
+ pnpm exec cef build
49
+ pnpm exec cef inspect dist/<agentId>
675
50
  ```
676
51
 
677
- `parameters` and `returns` are local-only. They drive dev UI input hints and output schema display. The MCP playground also uses `parameters` for tool argument schema.
678
-
679
- `batch_file` and `batch_cubby` are local dev only. When both are set, the dev UI shows a "Run Batch" button on the agent task panel. Clicking it runs the SQL from `batch_file` against `batch_cubby`, then calls the agent once per result row.
680
-
681
- ### Cubbies
682
-
683
- Cubbies are per-agent SQLite databases with versioned schema migrations.
684
-
685
- ```yaml
686
- cubbies:
687
- - alias: greetings # Required. Used in context.cubbies.{alias}.
688
- name: Greetings Store # Required. Display name.
689
- description: Stores greeting records # Optional.
690
- cubbyId: 53d8630e-... # Set by CLI on deploy. Do not set manually.
691
- maxSizeBytes: 10485760 # Optional. Max DB size in bytes.
692
- idleTimeout: 24h # Optional. Instance idle timeout.
693
- migrations:
694
- - version: 1 # Required. Integer, applied in order.
695
- up: | # Required. SQL DDL statements.
696
- CREATE TABLE greetings (
697
- id INTEGER PRIMARY KEY,
698
- name TEXT,
699
- message TEXT,
700
- created_at TEXT DEFAULT (datetime('now'))
701
- );
702
- CREATE INDEX idx_greetings_name ON greetings(name);
703
- - version: 2
704
- up: |
705
- ALTER TABLE greetings ADD COLUMN source TEXT DEFAULT 'manual';
706
- ```
707
-
708
- Migrations run in version order. Each `up` field can contain multiple SQL statements separated by semicolons. A `schema_migrations` table tracks applied versions.
709
-
710
- In the local dev server, cubbies are backed by real SQLite with `better-sqlite3` and `sqlite-vec` (vector operations). Pragmas applied: WAL journal mode, 64MB cache, 5s busy timeout, NORMAL synchronous mode.
711
-
712
- ### Workspaces
713
-
714
- Workspaces group related streams. Streams contain deployments (which bind engagements to event flows) and rafts (query interfaces).
715
-
716
- ```yaml
717
- workspaces:
718
- - name: Freemont # Required.
719
- description: Freemont zone # Optional.
720
- workspaceId: "2198" # Set by CLI on deploy.
721
- streams:
722
- - name: DSC 142 # Required.
723
- description: Camera feed DSC 142 # Optional.
724
- streamId: stream-f5213550 # Set by CLI on deploy.
725
- selectors: # Optional. Event type filters.
726
- - name: illegalParkingDetection
727
- conditions:
728
- - event_type:illegalParking
729
- deployments:
730
- - name: Illegal Parking Detection # Required.
731
- description: Detects violations # Optional.
732
- engagement: Illegal Parking detection # Required. References engagement by name.
733
- isActive: true # Optional. Default true.
734
- deploymentId: dep-21e72017 # Set by CLI on deploy.
735
- triggers: # Optional. Event matching rules.
736
- - name: all-events
737
- conditions:
738
- - "*"
739
- engagementRules: [] # Optional.
740
- rafts:
741
- - name: Query Interface # Required.
742
- description: Raft for queries # Optional.
743
- file: ./queries/raft.ts # Optional. Path to raft handler.
744
- raftId: raft-abc123 # Set by CLI on deploy.
745
- dataSourcesIds: [] # Optional.
746
- queryOperations: [] # Optional.
747
- ```
748
-
749
- Raft handlers export `onInit()`, `onData()`, `query()`, `onCleanup()` functions.
750
-
751
- ### Full Example Config
752
-
753
- A minimal working config (from `example/hello-world/cef.config.yaml`):
754
-
755
- ```yaml
756
- agentServicePubKey: "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
757
-
758
- workspaces:
759
- - name: Local Dev
760
- workspaceId: "local-ws-1"
761
-
762
- engagements:
763
- - name: Hello World
764
- file: ./engagements/hello-engagement.ts
765
- parameters:
766
- type: object
767
- properties:
768
- streamId:
769
- type: string
770
- description: Stream to subscribe to
771
- required: [streamId]
772
-
773
- agents:
774
- - name: Greeter
775
- alias: greeter
776
- tasks:
777
- - name: Greet
778
- alias: greet
779
- file: ./agents/greeter.ts
780
- parameters:
781
- type: object
782
- properties:
783
- name:
784
- type: string
785
- description: Name of the person to greet
786
- required: [name]
787
- returns:
788
- type: object
789
- properties:
790
- greeting:
791
- type: string
792
- timestamp:
793
- type: number
794
-
795
- - name: Summarizer
796
- alias: summarizer
797
- tasks:
798
- - name: Summarize
799
- alias: summarize
800
- file: ./agents/summarizer.ts
801
- parameters:
802
- type: object
803
- properties: {}
804
- returns:
805
- type: object
806
- properties:
807
- summary:
808
- type: string
809
- totalGreetings:
810
- type: number
811
-
812
- cubbies:
813
- - alias: greetings
814
- name: Greetings Store
815
- migrations:
816
- - version: 1
817
- up: "CREATE TABLE greetings (id INTEGER PRIMARY KEY, name TEXT, message TEXT, created_at TEXT DEFAULT (datetime('now')))"
818
- ```
52
+ ## Programmatic API
819
53
 
820
- A full reference config with workspaces, streams, deployments, and rafts is in the `example/` directory.
54
+ Every subcommand has a corresponding function exported from the package
55
+ root, useful from tests and scripts:
821
56
 
822
- ---
57
+ ```ts
58
+ import { cefBuild, cefTypegen, cefInspect } from "@cef-ai/cli";
823
59
 
824
- ## Agent Sandbox
825
-
826
- Agent and engagement handlers run in isolated V8 sandboxes using Node.js `vm` module. Each execution gets its own context with no access to the host environment.
827
-
828
- ### Handler Signature
829
-
830
- Every handler file must define an `async function handle`:
831
-
832
- ```typescript
833
- async function handle(event: any, context: any) {
834
- // event.payload contains the input data
835
- const name = event.payload.name;
836
-
837
- // Use context to interact with the platform
838
- context.log('Processing: ' + name);
839
-
840
- // Return a result
841
- return { greeting: `Hello, ${name}!` };
60
+ const build = await cefBuild({ cwd: process.cwd(), outDir: "dist" });
61
+ for (const a of build.agents) {
62
+ console.log(a.agentId, a.bundlePath, a.bundleBytes);
842
63
  }
843
- ```
844
-
845
- The function receives:
846
- - `event` with `event.payload` containing the input data
847
- - `context` providing platform APIs (logging, agents, cubbies, streams, fetch)
848
-
849
- The return value is sent back to the caller (another agent, the playground, or the dev UI).
850
-
851
- ### Available Globals
852
-
853
- The sandbox provides these globals and nothing else:
854
-
855
- | Global | Description |
856
- |-|-|
857
- | `event` | Input payload object (`event.payload` has the data) |
858
- | `context` | Platform API (see [Context API Reference](#context-api-reference)) |
859
- | `console` | `log`, `warn`, `error` (proxied to context logging) |
860
- | `Promise` | Standard Promise |
861
- | `JSON` | Standard JSON |
862
- | `TextDecoder` | Standard TextDecoder |
863
- | `TextEncoder` | Standard TextEncoder |
864
- | `Uint8Array` | Standard Uint8Array |
865
-
866
- ### Restrictions
867
-
868
- The following are **not available** in the sandbox:
869
-
870
- - `process` - no access to Node.js process
871
- - `require` / `import` - no module loading
872
- - `Buffer` - use `Uint8Array` and `TextEncoder`/`TextDecoder` instead
873
- - `fs` - no filesystem access
874
- - `global` / `globalThis` - isolated scope
875
- - Any Node.js built-in modules (`http`, `path`, `crypto`, etc.)
876
-
877
- All handler code must be fully self-contained. No `import` or `require` statements. This is a V8 isolate constraint; the same constraint applies to deployed handlers on the platform.
878
-
879
- ---
880
-
881
- ## Context API Reference
882
-
883
- The `context` object is injected into every handler and provides all platform interactions.
884
-
885
- ### Logging
886
-
887
- ```typescript
888
- context.log('info message', extraData);
889
- context.warn('warning message');
890
- context.error('error message');
891
- ```
892
-
893
- Logs appear in the dev server console, the dev UI live log panel, and are broadcast via WebSocket. Each log entry captures the execution ID, agent/task alias, timestamp, and level.
894
-
895
- `console.log`, `console.warn`, and `console.error` are proxied to the corresponding context methods.
896
-
897
- ### Event Emission
898
-
899
- ```typescript
900
- context.emit(eventType: string, payload: any, targetId?: string);
901
- ```
902
64
 
903
- Emits a custom event that appears in the trace log. Use for signaling between components or for custom instrumentation.
65
+ await cefTypegen({ configPath: "./cef.config.ts" });
904
66
 
905
- ### HTTP Fetch
906
-
907
- ```typescript
908
- const response = await context.fetch('https://api.example.com/data', {
909
- method: 'POST',
910
- headers: { 'Content-Type': 'application/json' },
911
- body: JSON.stringify({ key: 'value' })
67
+ const inspected = await cefInspect({
68
+ agentDir: "dist/echo",
69
+ print: false,
912
70
  });
913
- const data = await response.json();
914
- ```
915
-
916
- Standard fetch API. Available in both local dev and deployed environments. Use this for calling external APIs from within agent handlers.
917
-
918
- ### Agent-to-Agent Calls
919
-
920
- ```typescript
921
- const result = await context.agents.greeter.greet({ name: 'Alice' });
922
- const summary = await context.agents.summarizer.summarize({});
923
- ```
924
-
925
- Call any agent task by alias. The pattern is `context.agents.{agentAlias}.{taskAlias}(payload)`.
926
-
927
- Returns the handler's return value directly. Each call emits `agent:call` and `agent:return` trace events with timing information.
928
-
929
- ### Cubby Operations
930
-
931
- **Read query:**
932
-
933
- ```typescript
934
- // Default instance
935
- const result = await context.cubbies.greetings.query(
936
- 'SELECT name, message FROM greetings WHERE name = ?',
937
- ['Alice']
938
- );
939
- // result.columns = ['name', 'message']
940
- // result.rows = [['Alice', 'Hello, Alice!']]
941
- // result.meta = { duration: 2, rowsRead: 1 }
942
- ```
943
-
944
- **Write operation:**
945
-
946
- ```typescript
947
- const result = await context.cubbies.greetings.exec(
948
- 'INSERT INTO greetings (name, message) VALUES (?, ?)',
949
- ['Alice', 'Hello, Alice!']
950
- );
951
- // result.rowsAffected = 1
952
- // result.lastInsertId = 1
953
- // result.meta = { duration: 1 }
954
- ```
955
-
956
- **Named instances:**
957
-
958
- ```typescript
959
- // Query a specific instance
960
- const result = await context.cubbies.greetings.query(
961
- 'user-123',
962
- 'SELECT * FROM greetings',
963
- []
964
- );
965
-
966
- // Write to a specific instance
967
- await context.cubbies.greetings.exec(
968
- 'user-123',
969
- 'INSERT INTO greetings (name, message) VALUES (?, ?)',
970
- ['Bob', 'Hello, Bob!']
971
- );
972
- ```
973
-
974
- Both `query` and `exec` support an optional first argument for the instance ID. If the first argument contains a space, it is treated as SQL (using the `"default"` instance). Otherwise it is treated as an instance ID.
975
-
976
- Each operation emits `cubby:query` or `cubby:exec` trace events with timing and row counts.
977
-
978
- ### Stream Subscriptions
979
-
980
- Used in engagements to consume stream events:
981
-
982
- ```typescript
983
- async function handle(event: any, context: any) {
984
- const stream = await context.streams.subscribe(event.payload.streamId);
985
-
986
- for await (const packet of stream) {
987
- const payload = JSON.parse(new TextDecoder().decode(packet.payload));
988
- context.log('Received: ' + payload.event_type);
989
-
990
- // Process packet and call agents...
991
- }
992
- }
993
- ```
994
-
995
- Each packet has:
996
- - `sequenceNum` (number) - packet sequence number
997
- - `payload` (Uint8Array) - packet data, decode with `TextDecoder`
998
- - `metadata` (object, optional) - additional metadata
999
-
1000
- ### Raft Queries
1001
-
1002
- ```typescript
1003
- const data = await context.rafts.myRaft.query();
1004
- ```
1005
-
1006
- In local dev mode, raft queries throw `"not available in local dev mode"`. In deployed environments, rafts execute against their configured data sources and query operations.
1007
-
1008
- ---
1009
-
1010
- ## Authentication
1011
-
1012
- Run `cef login` to authenticate via browser. Credentials are saved to `~/.cef/credentials.json` and used automatically by all commands that require auth.
1013
-
1014
- ```bash
1015
- cef login # Opens browser, saves token
1016
- cef whoami # Check current auth status
1017
- cef logout # Clear stored credentials
71
+ console.log(inspected.exposedMethods, inspected.missingMethods);
1018
72
  ```
1019
73
 
1020
- No `.env` file is needed. All API URLs default to stage:
1021
-
1022
- | Variable | Default | Description |
1023
- |-|-|-|
1024
- | `CEF_ORCHESTRATOR_URL` | `https://orchestrator.compute.test.ddcdragon.com` | Orchestrator base URL |
1025
- | `CEF_ROB_API_URL` | `https://rob-api.compute.test.ddcdragon.com/rms-node-backend` | ROB API base URL |
1026
- | `CEF_ROB_ORIGIN` | (derived from ROB API URL) | Override Origin/Referer header |
1027
-
1028
- To override URLs, set them as environment variables or in a `.env` file next to your `cef.config.yaml`.
1029
-
1030
- `cef dev` does **not** require authentication or any environment variables.
1031
-
1032
- ---
1033
-
1034
- ## Options Reference
1035
-
1036
- | Option | Commands | Default | Description |
1037
- |-|-|-|-|
1038
- | `--config <path>` | all | `./cef.config.yaml` | Config file path |
1039
- | `--dry-run` | deploy | `false` | Show planned operations without calling the API |
1040
- | `--only <type>` | deploy, delete | (all) | Act on one entity type only |
1041
- | `--pubkey <key>` | clone | (from config) | Agent service public key (`0x...`) |
1042
- | `--output-dir <dir>` | clone | (config dir) | Directory to write cloned files into |
1043
- | `--force` | clone, delete | `false` | Skip confirmation / overwrite existing files |
1044
- | `--name <name>` | service create | - | Name of the new agent service (required) |
1045
- | `--bucket-id <id>` | service create | `1` | DDC bucket ID |
1046
- | `--port <port>` | dev | `8787` | Server port |
1047
- | `--host <host>` | dev | `localhost` | Server host |
1048
- | `--persist` | dev | `false` | Keep `.cef-dev/` data after shutdown |
1049
- | `--agent <name>` | playground test | - | Agent name, alias, or agentId |
1050
- | `--tool <alias>` | playground test | - | Task alias (tool name) to call |
1051
- | `--args <json>` | playground test | - | JSON arguments for tool |
1052
- | `--test-file <path>` | playground test | - | Path to cef.tests.yaml |
1053
- | `--list-tools` | playground test | `false` | List available tools on an agent |
1054
- | `-V, --version` | (global) | - | Show CLI version |
1055
- | `--help` | (global) | - | Show help |
1056
-
1057
- ---
1058
-
1059
- ## Examples
1060
-
1061
- ### Hello World
1062
-
1063
- A minimal topology with two agents sharing a cubby, driven by a stream-based engagement.
1064
-
1065
- **Engagement handler** (`engagements/hello-engagement.ts`):
1066
-
1067
- ```typescript
1068
- async function handle(event: any, context: any) {
1069
- const streamId = event.payload.streamId;
1070
- context.log('Hello engagement started, subscribing to stream: ' + streamId);
1071
-
1072
- const stream = await context.streams.subscribe(streamId);
1073
-
1074
- for await (const packet of stream) {
1075
- const data = JSON.parse(new TextDecoder().decode(packet.payload));
1076
- context.log('Received event: ' + data.event_type);
1077
-
1078
- if (data.event_type === 'GREET') {
1079
- const greetResult = await context.agents.greeter.greet({
1080
- name: data.name,
1081
- timestamp: data.timestamp,
1082
- });
1083
- context.log('Greet result: ' + JSON.stringify(greetResult));
1084
-
1085
- } else if (data.event_type === 'SUMMARIZE') {
1086
- const summaryResult = await context.agents.summarizer.summarize({});
1087
- context.log('Summary result: ' + JSON.stringify(summaryResult));
1088
- }
1089
- }
1090
- }
1091
- ```
1092
-
1093
- **Greeter agent** (`agents/greeter.ts`):
1094
-
1095
- ```typescript
1096
- async function handle(event: any, context: any) {
1097
- const name = event.payload.name || 'World';
1098
- context.log(`Greeter agent called with name: ${name}`);
1099
-
1100
- // Write to cubby
1101
- await context.cubbies.greetings.exec(
1102
- 'INSERT INTO greetings (name, message) VALUES (?, ?)',
1103
- [name, `Hello, ${name}!`]
1104
- );
1105
-
1106
- return { greeting: `Hello, ${name}!`, timestamp: Date.now() };
1107
- }
1108
- ```
1109
-
1110
- **Summarizer agent** (`agents/summarizer.ts`):
1111
-
1112
- ```typescript
1113
- async function handle(event: any, context: any) {
1114
- context.log('Summarizer agent called');
1115
-
1116
- // Read all greetings from cubby (cross-agent shared state)
1117
- const result = await context.cubbies.greetings.query(
1118
- 'SELECT name, message FROM greetings ORDER BY id'
1119
- );
1120
-
1121
- const names = result.rows.map((r: any) => r[0]);
1122
- const summary = `Greeted ${result.rows.length} people: ${names.join(', ')}`;
1123
-
1124
- context.log(`Summary: ${summary}`);
1125
- return { summary, totalGreetings: result.rows.length };
1126
- }
1127
- ```
1128
-
1129
- **Run it:**
1130
-
1131
- ```bash
1132
- # Start dev server
1133
- cef dev --config ./example/hello-world/cef.config.yaml
1134
-
1135
- # Call the greeter directly
1136
- curl -s -X POST http://localhost:8787/api/agents/greeter/greet \
1137
- -H "Content-Type: application/json" \
1138
- -d '{"payload": {"name": "Alice"}}'
1139
- # -> {"greeting":"Hello, Alice!","timestamp":1712345678000}
1140
-
1141
- # Greet again
1142
- curl -s -X POST http://localhost:8787/api/agents/greeter/greet \
1143
- -H "Content-Type: application/json" \
1144
- -d '{"payload": {"name": "Bob"}}'
1145
-
1146
- # Get summary (reads from same cubby)
1147
- curl -s -X POST http://localhost:8787/api/agents/summarizer/summarize \
1148
- -H "Content-Type: application/json" \
1149
- -d '{"payload": {}}'
1150
- # -> {"summary":"Greeted 2 people: Alice, Bob","totalGreetings":2}
1151
-
1152
- # Query the cubby directly
1153
- curl -s -X POST http://localhost:8787/api/cubbies/greetings/query \
1154
- -H "Content-Type: application/json" \
1155
- -d '{"sql": "SELECT * FROM greetings"}'
1156
- ```
1157
-
1158
- See `example/hello-world/` for the complete project.
1159
-
1160
- ### Drone Telemetry (Workspaces + Streams)
1161
-
1162
- A more complex topology with workspaces, streams, selectors, deployments, and triggers. This pattern is used when you need:
1163
-
1164
- - **Workspaces** to group related streams by location or domain
1165
- - **Streams** with **selectors** to filter incoming events by type
1166
- - **Deployments** that bind engagements to streams with trigger conditions
1167
- - **Rafts** for query interfaces over collected data
1168
-
1169
- ```yaml
1170
- workspaces:
1171
- - name: Freemont
1172
- streams:
1173
- - name: DSC 142
1174
- selectors:
1175
- - name: illegalParkingDetection
1176
- conditions:
1177
- - event_type:illegalParking
1178
- deployments:
1179
- - name: Illegal Parking Detection
1180
- engagement: Illegal Parking detection # references engagement by name
1181
- isActive: true
1182
- triggers:
1183
- - name: all-events
1184
- conditions:
1185
- - "*"
1186
-
1187
- agents:
1188
- - name: Object Detection
1189
- alias: objectDetection
1190
- tasks:
1191
- - name: Yolo
1192
- alias: yolo
1193
- file: ./agents/object-detection/tasks/yolo.ts
1194
- - name: Detect
1195
- alias: detect
1196
- file: ./agents/parking-violation-detector/tasks/detect.ts
1197
-
1198
- cubbies:
1199
- - alias: syncMission
1200
- name: Sync Mission
1201
- migrations:
1202
- - version: 1
1203
- up: |
1204
- CREATE TABLE missions (id TEXT PRIMARY KEY, status TEXT NOT NULL, drone_id TEXT, started_at TEXT, ended_at TEXT, created_at TEXT DEFAULT (datetime('now')));
1205
- CREATE TABLE violations (id TEXT PRIMARY KEY, mission_id TEXT NOT NULL, type TEXT NOT NULL, latitude REAL, longitude REAL, confidence REAL, detected_at TEXT NOT NULL, FOREIGN KEY (mission_id) REFERENCES missions(id));
1206
- CREATE INDEX idx_violations_mission ON violations(mission_id);
1207
- ```
1208
-
1209
- See `example/cef.config.yaml` for the complete drone telemetry config.
1210
-
1211
- ### Wiki Knowledge Graph (Graph Viz + Batch)
1212
-
1213
- A knowledge graph pipeline that ingests Notion pages as versioned artifact nodes, evaluates changes with an LLM, and visualizes the result as a graph. Demonstrates graph visualization, saved queries, and batch execution.
1214
-
1215
- ```bash
1216
- cd example/wiki-graph
1217
- cef dev --config cef.config.yaml
1218
-
1219
- # Seed saved queries (first time)
1220
- node connector/seed-queries.js
1221
-
1222
- # Ingest test data via the UI (Graph Ingest Handler -> blast mode with test-events.json)
1223
- # Or ingest a real Notion page:
1224
- NOTION_API_KEY=... node connector/ingest-graph.js --page-id <notion_id>
1225
-
1226
- # Run evals via UI (Run Batch on graph-eval-agent.eval-page) or CLI:
1227
- node connector/run-evals.js
1228
- ```
1229
-
1230
- Graph schema: `artifact`, `work`, `operator`, `eval` nodes with relationship edges (`ADDED`, `CHANGED`, `OWNS`, `HAS_EVAL`, etc.). See `example/wiki-graph/README.md` for full details.
1231
-
1232
- ---
1233
-
1234
- ## Testing
1235
-
1236
- ```bash
1237
- npm test # Unit tests (Vitest)
1238
- npm run test:watch # Watch mode
1239
- npm run test:coverage # Coverage report
1240
- npm run test:integration # Integration tests (real API calls)
1241
- npm run test:e2e # E2E tests (full deploy cycle, slow)
1242
- npm run lint # ESLint
1243
- npm run build # Build TypeScript
1244
- ```
1245
-
1246
- | Suite | When to use | Auth needed | Speed |
1247
- |-|-|-|-|
1248
- | Unit (`npm test`) | Always; validates logic without external deps | No | Fast |
1249
- | Integration | Verify API client against dev environment | Yes (`cef login`) | Medium |
1250
- | E2E | Full lifecycle: deploy, test, delete | Yes (`cef login` + `CEF_E2E_AGENT_SERVICE_PUB_KEY`) | Slow (120s timeout) |
1251
-
1252
- For integration/E2E: run `cef login` first, then set `CEF_E2E_AGENT_SERVICE_PUB_KEY` in `.env.e2e`.
1253
-
1254
- ---
1255
-
1256
- ## Troubleshooting
74
+ ## Build-time lints
1257
75
 
1258
- **"Not authenticated" on deploy**
1259
- Run `cef login` to authenticate via browser. See [Authentication](#authentication).
76
+ `cef build` runs a syntactic lint pass over the agent's entry file before
77
+ bundling. Failures abort the build with a single, actionable message. The
78
+ rules mirror those in [`@cef-ai/eslint-plugin`](../eslint-plugin) so editor
79
+ warnings agree with CI failures.
1260
80
 
1261
- **Stale IDs after copying config between services**
1262
- If you copied a `cef.config.yaml` from another service, the embedded IDs point to the wrong service. Run `cef deploy` and accept the prompt to clear all IDs, or manually remove all `*Id` fields from the config.
81
+ - `@OnEvent(...)` argument must be a string literal.
82
+ - `ctx.publish(t, ...)` first argument must be a string literal.
83
+ - `ctx.cubby("alias")` argument must be a literal AND a declared alias in
84
+ `cef.config.ts` `cubbies[].alias`.
85
+ - `ctx.models.X` member must reference a declared model alias.
86
+ - Imports must not target the banned module list (Node built-ins like
87
+ `fs`, `net`, `http`, `child_process`, plus sync DB / network npm
88
+ packages). Agents call `ctx.fetch` for HTTP and `ctx.cubby` for state;
89
+ `globalThis.crypto` (WebCrypto) replaces `node:crypto`.
1263
90
 
1264
- **"require is not defined" or "import is not supported" in agent code**
1265
- Agent handlers run in a V8 sandbox with no module system. All code must be self-contained in a single file with no imports. See [Agent Sandbox](#agent-sandbox).
91
+ The full banned-module list and rationale live in `agent-sdk.md` §7.
1266
92
 
1267
- **Cubby data disappears after restarting dev server**
1268
- By default, `.cef-dev/` is deleted on shutdown. Use `cef dev --persist` to keep data between runs.
93
+ ## Companion packages
1269
94
 
1270
- **"Not available in local dev mode" for raft queries**
1271
- Raft queries are not emulated locally. Test rafts by deploying to the platform and using `cef playground test`.
95
+ - [`@cef-ai/agent-sdk`](../agent-sdk) — the decorators, `Context`, and
96
+ `defineAgent` consumed by the agent code being built.
97
+ - [`@cef-ai/testing`](../testing) — simulator harness used by `cef test`
98
+ once it lands.
99
+ - [`@cef-ai/eslint-plugin`](../eslint-plugin) — editor-time lints that
100
+ match the build-time enforcement.
1272
101
 
1273
- **Agent code changes not taking effect**
1274
- The dev server hot-reloads on file save. Check that the file path in `cef.config.yaml` matches the file you are editing. In-flight executions continue with old code; only new calls use the updated version.
102
+ ## References
1275
103
 
1276
- **Deploy fails with 404 on update**
1277
- The entity ID in config points to something that no longer exists on the orchestrator. Clear the ID field for that entity and re-run `cef deploy` to create it fresh.
104
+ - Agent SDK spec: `../../../company-memory-bank/specs/platform/03-components/agent-sdk.md`
105
+ - Runtime integration contract: `../../../company-memory-bank/specs/platform/03-components/sdk-runtime-integration-contract.md`
1278
106
 
1279
- **Non-interactive terminal and delete/deploy prompts**
1280
- Some operations prompt for confirmation. In CI or non-interactive environments, use `--force` to skip prompts.
107
+ The `../company-memory-bank/...` paths point at an internal sibling repo
108
+ and are not browsable from a fresh clone.