@cef-ai/cli 0.2.7 → 0.4.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 (153) 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-program.d.ts +14 -0
  27. package/dist/cli-program.d.ts.map +1 -0
  28. package/dist/cli-program.js +171 -0
  29. package/dist/cli-program.js.map +1 -0
  30. package/dist/cli.d.ts +2 -2
  31. package/dist/cli.d.ts.map +1 -0
  32. package/dist/cli.js +25 -65
  33. package/dist/cli.js.map +1 -0
  34. package/dist/commands/build.d.ts +41 -0
  35. package/dist/commands/build.d.ts.map +1 -0
  36. package/dist/commands/build.js +252 -0
  37. package/dist/commands/build.js.map +1 -0
  38. package/dist/commands/inspect.d.ts +49 -0
  39. package/dist/commands/inspect.d.ts.map +1 -0
  40. package/dist/commands/inspect.js +135 -0
  41. package/dist/commands/inspect.js.map +1 -0
  42. package/dist/commands/keypair.d.ts +21 -0
  43. package/dist/commands/keypair.d.ts.map +1 -0
  44. package/dist/commands/keypair.js +91 -0
  45. package/dist/commands/keypair.js.map +1 -0
  46. package/dist/commands/publish.d.ts +40 -0
  47. package/dist/commands/publish.d.ts.map +1 -0
  48. package/dist/commands/publish.js +187 -0
  49. package/dist/commands/publish.js.map +1 -0
  50. package/dist/commands/typegen.d.ts +36 -0
  51. package/dist/commands/typegen.d.ts.map +1 -0
  52. package/dist/commands/typegen.js +210 -0
  53. package/dist/commands/typegen.js.map +1 -0
  54. package/dist/index.d.ts +6 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +6 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/lib/cid.d.ts +3 -0
  59. package/dist/lib/cid.d.ts.map +1 -0
  60. package/dist/lib/cid.js +43 -0
  61. package/dist/lib/cid.js.map +1 -0
  62. package/dist/lib/credentials.d.ts +40 -16
  63. package/dist/lib/credentials.d.ts.map +1 -0
  64. package/dist/lib/credentials.js +222 -49
  65. package/dist/lib/credentials.js.map +1 -0
  66. package/dist/lib/jcs.d.ts +3 -0
  67. package/dist/lib/jcs.d.ts.map +1 -0
  68. package/dist/lib/jcs.js +48 -0
  69. package/dist/lib/jcs.js.map +1 -0
  70. package/dist/lib/signing.d.ts +13 -0
  71. package/dist/lib/signing.d.ts.map +1 -0
  72. package/dist/lib/signing.js +34 -0
  73. package/dist/lib/signing.js.map +1 -0
  74. package/dist/lib.d.ts +18 -0
  75. package/dist/lib.d.ts.map +1 -0
  76. package/dist/lib.js +12 -0
  77. package/dist/lib.js.map +1 -0
  78. package/dist/typegen/augment.d.ts +57 -0
  79. package/dist/typegen/augment.d.ts.map +1 -0
  80. package/dist/typegen/augment.js +87 -0
  81. package/dist/typegen/augment.js.map +1 -0
  82. package/dist/typegen/fetch.d.ts +30 -0
  83. package/dist/typegen/fetch.d.ts.map +1 -0
  84. package/dist/typegen/fetch.js +38 -0
  85. package/dist/typegen/fetch.js.map +1 -0
  86. package/dist/typegen/lockfile.d.ts +42 -0
  87. package/dist/typegen/lockfile.d.ts.map +1 -0
  88. package/dist/typegen/lockfile.js +58 -0
  89. package/dist/typegen/lockfile.js.map +1 -0
  90. package/dist/typegen/schema-to-ts.d.ts +21 -0
  91. package/dist/typegen/schema-to-ts.d.ts.map +1 -0
  92. package/dist/typegen/schema-to-ts.js +29 -0
  93. package/dist/typegen/schema-to-ts.js.map +1 -0
  94. package/package.json +23 -58
  95. package/dist/commands/auth/index.d.ts +0 -2
  96. package/dist/commands/auth/index.js +0 -162
  97. package/dist/commands/deploy/clone.d.ts +0 -13
  98. package/dist/commands/deploy/clone.js +0 -143
  99. package/dist/commands/deploy/delete.d.ts +0 -14
  100. package/dist/commands/deploy/delete.js +0 -134
  101. package/dist/commands/deploy/deploy.d.ts +0 -24
  102. package/dist/commands/deploy/deploy.js +0 -654
  103. package/dist/commands/deploy/index.d.ts +0 -2
  104. package/dist/commands/deploy/index.js +0 -216
  105. package/dist/commands/deploy/status.d.ts +0 -14
  106. package/dist/commands/deploy/status.js +0 -61
  107. package/dist/commands/dev/index.d.ts +0 -2
  108. package/dist/commands/dev/index.js +0 -134
  109. package/dist/commands/dev/server.d.ts +0 -14
  110. package/dist/commands/dev/server.js +0 -195
  111. package/dist/commands/dev/static/app.js +0 -633
  112. package/dist/commands/dev/static/index.html +0 -205
  113. package/dist/commands/dev/static/static/app.js +0 -633
  114. package/dist/commands/dev/static/static/index.html +0 -205
  115. package/dist/commands/dev/static/static/style.css +0 -184
  116. package/dist/commands/dev/static/style.css +0 -184
  117. package/dist/commands/playground/index.d.ts +0 -2
  118. package/dist/commands/playground/index.js +0 -75
  119. package/dist/commands/playground/test.d.ts +0 -15
  120. package/dist/commands/playground/test.js +0 -166
  121. package/dist/commands/service/index.d.ts +0 -2
  122. package/dist/commands/service/index.js +0 -89
  123. package/dist/lib/api.d.ts +0 -146
  124. package/dist/lib/api.js +0 -330
  125. package/dist/lib/config.d.ts +0 -12
  126. package/dist/lib/config.js +0 -145
  127. package/dist/lib/runtime/agent-router.d.ts +0 -12
  128. package/dist/lib/runtime/agent-router.js +0 -67
  129. package/dist/lib/runtime/context-builder.d.ts +0 -27
  130. package/dist/lib/runtime/context-builder.js +0 -166
  131. package/dist/lib/runtime/cubby-manager.d.ts +0 -20
  132. package/dist/lib/runtime/cubby-manager.js +0 -162
  133. package/dist/lib/runtime/index.d.ts +0 -51
  134. package/dist/lib/runtime/index.js +0 -181
  135. package/dist/lib/runtime/log-collector.d.ts +0 -17
  136. package/dist/lib/runtime/log-collector.js +0 -61
  137. package/dist/lib/runtime/stream-manager.d.ts +0 -10
  138. package/dist/lib/runtime/stream-manager.js +0 -77
  139. package/dist/lib/runtime/types.d.ts +0 -76
  140. package/dist/lib/runtime/types.js +0 -2
  141. package/dist/lib/transpile.d.ts +0 -1
  142. package/dist/lib/transpile.js +0 -9
  143. package/dist/lib/typecheck.d.ts +0 -31
  144. package/dist/lib/typecheck.js +0 -175
  145. package/dist/lib/types.d.ts +0 -246
  146. package/dist/lib/types.js +0 -2
  147. package/dist/lib/utils.d.ts +0 -4
  148. package/dist/lib/utils.js +0 -33
  149. package/example/.env.example +0 -6
  150. package/example/agents/object-detection/tasks/yolo.ts +0 -28
  151. package/example/agents/parking-violation-detector/tasks/detect.ts +0 -326
  152. package/example/cef.config.yaml +0 -91
  153. package/example/engagements/engagement.ts +0 -902
@@ -0,0 +1,150 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ import * as esbuild from "esbuild";
6
+ /**
7
+ * Walk up from `start` looking for an existing `node_modules` directory.
8
+ * We need this because the externalised `@cef-ai/agent-sdk` reference in the
9
+ * compiled config file is resolved by node's ESM loader from the file's
10
+ * location — so the temp file must sit somewhere whose ancestors include
11
+ * a `node_modules` containing `@cef-ai/agent-sdk`.
12
+ *
13
+ * Returns the *parent* directory (i.e. the directory that *contains* the
14
+ * `node_modules`), or `null` if none was found.
15
+ */
16
+ async function findNodeModulesParent(start) {
17
+ let dir = path.resolve(start);
18
+ while (true) {
19
+ try {
20
+ const stat = await fs.stat(path.join(dir, "node_modules"));
21
+ if (stat.isDirectory())
22
+ return dir;
23
+ }
24
+ catch {
25
+ // not here, keep walking up
26
+ }
27
+ const parent = path.dirname(dir);
28
+ if (parent === dir)
29
+ return null;
30
+ dir = parent;
31
+ }
32
+ }
33
+ /**
34
+ * Compile `cef.config.ts` to a temp ESM file and dynamically import it.
35
+ *
36
+ * `@cef-ai/agent-sdk` and `@cef-ai/agent-sdk/config` are externalised so the
37
+ * `defineAgent` identity helper resolves from the host's node_modules at
38
+ * runtime — we don't want to bundle the SDK into the user's config.
39
+ *
40
+ * The temp file is placed inside an existing `node_modules` ancestor of
41
+ * the config (under `node_modules/.cef/config-cache/`), so node's ESM
42
+ * resolver finds the externalised packages without us having to create a
43
+ * stub `node_modules` next to the user's config.
44
+ *
45
+ * Shared by `cef build` and `cef typegen`.
46
+ */
47
+ export async function loadConfig(configPath, configDir) {
48
+ const nmParent = await findNodeModulesParent(configDir);
49
+ if (!nmParent) {
50
+ throw new Error(`[@cef-ai/cli] could not find a node_modules ancestor of ${configDir}; install dependencies first`);
51
+ }
52
+ const tmpDir = path.join(nmParent, "node_modules", ".cef", "config-cache");
53
+ await fs.mkdir(tmpDir, { recursive: true });
54
+ const tmpFile = path.join(tmpDir, `config-${process.pid}-${crypto.randomBytes(6).toString("hex")}.mjs`);
55
+ try {
56
+ await esbuild.build({
57
+ entryPoints: [configPath],
58
+ bundle: true,
59
+ format: "esm",
60
+ platform: "node",
61
+ target: "es2022",
62
+ outfile: tmpFile,
63
+ logLevel: "silent",
64
+ // Resolve these from the host package's node_modules at runtime.
65
+ external: ["@cef-ai/agent-sdk", "@cef-ai/agent-sdk/*"],
66
+ });
67
+ const mod = await import(pathToFileURL(tmpFile).href);
68
+ const cfg = mod.default;
69
+ if (!cfg || typeof cfg !== "object") {
70
+ throw new Error(`[@cef-ai/cli] ${configPath} must default-export an AgentConfig (got ${typeof cfg})`);
71
+ }
72
+ return cfg;
73
+ }
74
+ finally {
75
+ // Best-effort cleanup; ignore if already gone.
76
+ await fs.unlink(tmpFile).catch(() => { });
77
+ }
78
+ }
79
+ /**
80
+ * Flatten a (possibly nested) `AgentConfig` into a list of leaf agents.
81
+ * The single-agent case is a top-level config with `entry` (or
82
+ * `engagements`). The nested-agents case has an `agents[]` field; each
83
+ * entry is a full AgentConfig and is recursed into. We require either
84
+ * `entry` or `engagements[]` on every leaf.
85
+ */
86
+ export function flattenAgents(cfg) {
87
+ if (cfg.agents && cfg.agents.length > 0) {
88
+ return cfg.agents.flatMap((a) => flattenAgents(a));
89
+ }
90
+ if (!cfg.entry && (!cfg.engagements || cfg.engagements.length === 0)) {
91
+ throw new Error(`[@cef-ai/cli] AgentConfig "${cfg.id}" has no \`entry\`, no \`engagements[]\`, and no nested \`agents[]\``);
92
+ }
93
+ return [cfg];
94
+ }
95
+ /** Regex for a stable engagement id. Letters/digits/underscore/dash, must
96
+ * start with a letter (mirrors typical identifier rules; "default" is fine). */
97
+ const ENGAGEMENT_ID_RE = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
98
+ /**
99
+ * Normalize an agent's engagement-layer declaration into a list with absolute
100
+ * entry paths. Accepts either:
101
+ *
102
+ * - `entry: "./src/agent.ts"` shorthand → one engagement with id `"default"`.
103
+ * - `engagements: [{ id, entry }, ...]` explicit form → returned as-is with
104
+ * relative entry paths resolved against `configDir`.
105
+ *
106
+ * Validates:
107
+ * - exactly one of `entry`/`engagements` is provided,
108
+ * - `engagements[]` has at least one entry when present,
109
+ * - every engagement id matches `[a-zA-Z][a-zA-Z0-9_-]*`,
110
+ * - engagement ids are unique within the agent.
111
+ *
112
+ * Throws on any violation with `[@cef-ai/cli]`-prefixed errors so failures point
113
+ * authors at their `cef.config.ts`.
114
+ */
115
+ export function normalizeEngagements(agent, configDir) {
116
+ const hasEntry = typeof agent.entry === "string" && agent.entry.length > 0;
117
+ const hasList = Array.isArray(agent.engagements) && agent.engagements.length > 0;
118
+ if (hasEntry && hasList) {
119
+ throw new Error(`[@cef-ai/cli] agent "${agent.id}": specify either 'entry' or 'engagements', not both`);
120
+ }
121
+ if (!hasEntry && !hasList) {
122
+ throw new Error(`[@cef-ai/cli] agent "${agent.id}": missing 'entry' or 'engagements'`);
123
+ }
124
+ if (agent.engagements && agent.engagements.length === 0) {
125
+ throw new Error(`[@cef-ai/cli] agent "${agent.id}": 'engagements' must contain at least one entry`);
126
+ }
127
+ const list = hasList
128
+ ? agent.engagements
129
+ : [{ id: "default", entry: agent.entry }];
130
+ const seen = new Set();
131
+ const out = [];
132
+ for (const e of list) {
133
+ if (typeof e.id !== "string" || e.id.length === 0) {
134
+ throw new Error(`[@cef-ai/cli] agent "${agent.id}": engagement entry has empty 'id'`);
135
+ }
136
+ if (!ENGAGEMENT_ID_RE.test(e.id)) {
137
+ throw new Error(`[@cef-ai/cli] engagement id "${e.id}" must match /^[a-zA-Z][a-zA-Z0-9_-]*$/`);
138
+ }
139
+ if (seen.has(e.id)) {
140
+ throw new Error(`[@cef-ai/cli] duplicate engagement id "${e.id}"`);
141
+ }
142
+ seen.add(e.id);
143
+ if (typeof e.entry !== "string" || e.entry.length === 0) {
144
+ throw new Error(`[@cef-ai/cli] agent "${agent.id}": engagement "${e.id}" has empty 'entry'`);
145
+ }
146
+ out.push({ id: e.id, entry: path.resolve(configDir, e.entry) });
147
+ }
148
+ return out;
149
+ }
150
+ //# sourceMappingURL=load-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../src/build/load-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ import type { AgentCard, JSONSchema, Targeting } from "./load-config.js";
2
+ /**
3
+ * Per-engagement manifest input. Each engagement carries its own routing
4
+ * (`events` map) and its lifecycle method names (extracted from decorator
5
+ * metadata). The manifest emitter:
6
+ *
7
+ * - copies `events` into the per-engagement `handles` map (eventType →
8
+ * handlerName, per `prototype.md` §"AgentManifest.Engagements");
9
+ * - aggregates `events` keys + caller-provided `publishes` into the
10
+ * top-level derived unions;
11
+ * - drops `lifecycle` from the manifest output entirely — `onStart` /
12
+ * `onClose` are conventional method names invoked by the runtime if
13
+ * defined on the class (per prototype.md §"Notes on the simplifications").
14
+ */
15
+ export interface ManifestEngagementInput {
16
+ id: string;
17
+ goal?: string;
18
+ events: Record<string, string>;
19
+ /** Recorded for the simulator — not emitted into the wire manifest. */
20
+ lifecycle: {
21
+ start?: string;
22
+ close?: string;
23
+ };
24
+ /** Event types this engagement publishes (lint-derived or author-pinned). */
25
+ publishes: string[];
26
+ }
27
+ /**
28
+ * Subset of `AgentConfig` (from `@cef-ai/agent-sdk/config`) that the manifest
29
+ * emitter consumes at the agent level. Per-engagement state lives on
30
+ * {@link ManifestEngagementInput}.
31
+ */
32
+ export interface ManifestConfigInput {
33
+ alias?: string;
34
+ source?: string;
35
+ card?: AgentCard;
36
+ requiredScopes?: string[];
37
+ /** Per-Job idle timeout as a duration string (e.g. `"15m"`); the
38
+ * manifest emitter parses this into integer ms. Defaults to `"30m"`. */
39
+ idleTimeout?: string;
40
+ cubbies?: Array<{
41
+ alias: string;
42
+ migrations?: string;
43
+ }>;
44
+ settings?: Array<{
45
+ key: string;
46
+ type: "string" | "number" | "boolean" | "url" | "secret";
47
+ required?: boolean;
48
+ label?: string;
49
+ description?: string;
50
+ default?: unknown;
51
+ }>;
52
+ models?: Record<string, string>;
53
+ uses?: Record<string, string>;
54
+ eventSchemas?: Record<string, JSONSchema>;
55
+ }
56
+ export interface ManifestInput {
57
+ /** Marketplace alias / build id (becomes `manifest.alias`). */
58
+ agentId: string;
59
+ version: string;
60
+ /** Absolute path to the IIFE bundle whose source is embedded as
61
+ * `manifest.bundle` (per prototype.md §"AgentManifest.Bundle"). */
62
+ bundlePath: string;
63
+ /** One entry per engagement. At least one required. */
64
+ engagements: ManifestEngagementInput[];
65
+ /** Declarative bits taken from cef.config.ts (agent-level). */
66
+ config: ManifestConfigInput;
67
+ /**
68
+ * Directory containing the user's cef.config.ts — used to resolve
69
+ * relative `cubbies[].migrations` paths.
70
+ */
71
+ configDir: string;
72
+ /**
73
+ * Validated targeting decision table. Caller (build pipeline) is
74
+ * responsible for running `validateTargeting` first; the manifest
75
+ * emitter just writes this verbatim into the JSON.
76
+ */
77
+ targeting: Targeting;
78
+ }
79
+ export interface InlinedCubby {
80
+ alias: string;
81
+ migrations?: Array<{
82
+ version: number;
83
+ up: string;
84
+ }>;
85
+ }
86
+ /**
87
+ * Per-engagement slice of the emitted manifest (per prototype.md
88
+ * §"EngagementDecl"). `handles` is a map (eventType → handlerName); per-
89
+ * engagement `publishes` and `lifecycleHandlers` are intentionally NOT
90
+ * emitted — the contract carries publishes at the agent level only and
91
+ * lifecycle hook resolution is conventional (instance.onStart /
92
+ * instance.onClose if defined).
93
+ */
94
+ export interface ManifestEngagement {
95
+ id: string;
96
+ goal: string;
97
+ handles: Record<string, string>;
98
+ }
99
+ /** Settings declaration as emitted into the manifest. */
100
+ export type ManifestSetting = NonNullable<ManifestConfigInput["settings"]>[number];
101
+ /**
102
+ * Manifest body per `prototype.md` §"AgentManifest". Identity / signature
103
+ * fields (`agentId`, `agentServicePubkey`, `signature`) are filled in by
104
+ * `cef publish` after Ed25519 signing — they are emitted as empty strings
105
+ * by `cef build`.
106
+ */
107
+ export interface CefManifest {
108
+ agentId: string;
109
+ agentServicePubkey: string;
110
+ version: string;
111
+ alias: string;
112
+ card: AgentCard;
113
+ requiredScopes: string[];
114
+ /** Per-Job idle timeout in milliseconds (orchestrator sweeper marks the
115
+ * Job terminal after this much inactivity). `0` disables idle-based
116
+ * termination. */
117
+ idleTimeout: number;
118
+ settings: ManifestSetting[];
119
+ bundle: string;
120
+ engagements: ManifestEngagement[];
121
+ /** Derived union of every engagement's `handles` keys (sorted). */
122
+ handles: string[];
123
+ /** Derived union of every engagement's lint-derived publishes (sorted). */
124
+ publishes: string[];
125
+ eventSchemas: Record<string, JSONSchema>;
126
+ cubbies: InlinedCubby[];
127
+ models: Record<string, string>;
128
+ uses: Record<string, string>;
129
+ targeting: Targeting;
130
+ source: string;
131
+ signature: string;
132
+ }
133
+ /**
134
+ * Build the manifest object per `prototype.md` §"AgentManifest". The shape
135
+ * is the single self-contained artifact used by Marketplace, Vault API,
136
+ * Cubby Manager, Event Runtime, Orchestrator, Agent Runtime, and `cef
137
+ * typegen` — everything an agent needs at runtime is inline.
138
+ *
139
+ * Per-engagement: `handles` is a map (eventType → handlerName), sorted
140
+ * alphabetically by key. Per-engagement publishes / lifecycleHandlers are
141
+ * NOT emitted — see `prototype.md` §"Notes on the simplifications" and
142
+ * the `EngagementDecl` go type.
143
+ *
144
+ * Agent-level: `cubbies[]` inlines each cubby's migration directory;
145
+ * `bundle` embeds the JS source as a JSON-escaped string (no separate
146
+ * `codeCid`); `handles[]` and `publishes[]` are derived unions over the
147
+ * engagements; identity / signature fields are placeholders to be set by
148
+ * `cef publish`.
149
+ */
150
+ export declare function buildManifest(input: ManifestInput): Promise<CefManifest>;
151
+ /**
152
+ * Build the manifest and write it as pretty-printed JSON to `out`. Returns
153
+ * the manifest object so callers don't need to re-read the file.
154
+ */
155
+ export declare function emitManifest(out: string, input: ManifestInput): Promise<CefManifest>;
156
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/build/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parseDuration } from "./duration.js";
4
+ const EMPTY_CARD = { name: "", description: "" };
5
+ /** Default idle timeout — author-facing string; see `AgentConfig.idleTimeout`. */
6
+ const DEFAULT_IDLE_TIMEOUT = "30m";
7
+ /**
8
+ * Read `<dir>/*.sql` in lexical order and return inlined migrations. The
9
+ * version is parsed from the leading integer of the filename (`001-init.sql`
10
+ * → 1). Files whose name does not start with digits are rejected with an
11
+ * Error so authors don't silently get unordered migrations.
12
+ */
13
+ async function readMigrations(dir) {
14
+ const entries = await fs.readdir(dir);
15
+ const sql = entries.filter((f) => f.toLowerCase().endsWith(".sql")).sort();
16
+ const out = [];
17
+ for (const file of sql) {
18
+ const m = /^(\d+)/.exec(file);
19
+ if (!m) {
20
+ throw new Error(`[@cef-ai/cli] migration filename must start with digits (got "${file}" in ${dir})`);
21
+ }
22
+ const version = Number.parseInt(m[1], 10);
23
+ const up = await fs.readFile(path.join(dir, file), "utf8");
24
+ out.push({ version, up });
25
+ }
26
+ return out;
27
+ }
28
+ /**
29
+ * Build the manifest object per `prototype.md` §"AgentManifest". The shape
30
+ * is the single self-contained artifact used by Marketplace, Vault API,
31
+ * Cubby Manager, Event Runtime, Orchestrator, Agent Runtime, and `cef
32
+ * typegen` — everything an agent needs at runtime is inline.
33
+ *
34
+ * Per-engagement: `handles` is a map (eventType → handlerName), sorted
35
+ * alphabetically by key. Per-engagement publishes / lifecycleHandlers are
36
+ * NOT emitted — see `prototype.md` §"Notes on the simplifications" and
37
+ * the `EngagementDecl` go type.
38
+ *
39
+ * Agent-level: `cubbies[]` inlines each cubby's migration directory;
40
+ * `bundle` embeds the JS source as a JSON-escaped string (no separate
41
+ * `codeCid`); `handles[]` and `publishes[]` are derived unions over the
42
+ * engagements; identity / signature fields are placeholders to be set by
43
+ * `cef publish`.
44
+ */
45
+ export async function buildManifest(input) {
46
+ const { agentId, version, bundlePath, engagements, config, configDir, targeting, } = input;
47
+ if (engagements.length === 0) {
48
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": manifest needs at least one engagement`);
49
+ }
50
+ const sortedEngagements = [...engagements].sort((a, b) => a.id.localeCompare(b.id));
51
+ const allHandles = new Set();
52
+ const allPublishes = new Set();
53
+ const manifestEngagements = sortedEngagements.map((e) => {
54
+ const handles = {};
55
+ for (const type of Object.keys(e.events).sort()) {
56
+ handles[type] = e.events[type];
57
+ allHandles.add(type);
58
+ }
59
+ for (const t of e.publishes)
60
+ allPublishes.add(t);
61
+ return {
62
+ id: e.id,
63
+ goal: e.goal ?? "",
64
+ handles,
65
+ };
66
+ });
67
+ const cubbies = [];
68
+ for (const c of config.cubbies ?? []) {
69
+ const inlined = { alias: c.alias };
70
+ if (c.migrations) {
71
+ const dir = path.resolve(configDir, c.migrations);
72
+ inlined.migrations = await readMigrations(dir);
73
+ }
74
+ cubbies.push(inlined);
75
+ }
76
+ const bundle = await fs.readFile(bundlePath, "utf8");
77
+ return {
78
+ // Identity placeholders — `cef publish` sets these after signing
79
+ // (per prototype.md → POST /api/v1/marketplace/agents).
80
+ agentId: "",
81
+ agentServicePubkey: "",
82
+ version,
83
+ alias: config.alias ?? agentId,
84
+ card: config.card ?? EMPTY_CARD,
85
+ requiredScopes: config.requiredScopes ?? ["default"],
86
+ idleTimeout: parseDuration(config.idleTimeout ?? DEFAULT_IDLE_TIMEOUT, `agent "${agentId}" idleTimeout`),
87
+ settings: config.settings ?? [],
88
+ bundle,
89
+ engagements: manifestEngagements,
90
+ handles: [...allHandles].sort(),
91
+ publishes: [...allPublishes].sort(),
92
+ eventSchemas: config.eventSchemas ?? {},
93
+ cubbies,
94
+ models: config.models ?? {},
95
+ uses: config.uses ?? {},
96
+ targeting,
97
+ source: config.source ?? "",
98
+ signature: "",
99
+ };
100
+ }
101
+ /**
102
+ * Build the manifest and write it as pretty-printed JSON to `out`. Returns
103
+ * the manifest object so callers don't need to re-read the file.
104
+ */
105
+ export async function emitManifest(out, input) {
106
+ const manifest = await buildManifest(input);
107
+ await fs.mkdir(path.dirname(out), { recursive: true });
108
+ await fs.writeFile(out, JSON.stringify(manifest, null, 2) + "\n", "utf8");
109
+ return manifest;
110
+ }
111
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/build/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Targeting } from "./load-config.js";
2
+ export interface ValidateTargetingInput {
3
+ /** Agent id used in error messages. */
4
+ agentId: string;
5
+ /** Declared engagement ids (post-normalize). At least one required. */
6
+ engagementIds: string[];
7
+ /** The user's optional targeting block. */
8
+ targeting?: Targeting;
9
+ }
10
+ export interface ValidateTargetingResult {
11
+ /** Validated targeting (defaulted when input was absent). */
12
+ targeting: Targeting;
13
+ }
14
+ export declare function validateTargeting(input: ValidateTargetingInput): ValidateTargetingResult;
15
+ //# sourceMappingURL=targeting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targeting.d.ts","sourceRoot":"","sources":["../../src/build/targeting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,SAAS,EAAuB,MAAM,kBAAkB,CAAC;AAwB7E,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,6DAA6D;IAC7D,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,uBAAuB,CA8BzB"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Build-time targeting validator (per prototype.md → "Targeting on the
3
+ * Manifest body"). The user authors a `targeting` block in `cef.config.ts`
4
+ * matching the platform's selection-table shape; the build step:
5
+ *
6
+ * - defaults `targeting` to a single entry over the first declared
7
+ * engagement when omitted (single-engagement agents don't need a block);
8
+ * - rejects ids that do not match a declared engagement;
9
+ * - rejects rule names outside the v1 vocabulary (`priority` | `weight` |
10
+ * `limit`) so authors get a fail-fast message instead of silently
11
+ * misrouted traffic.
12
+ *
13
+ * Failures throw with `[@cef-ai/cli]`-prefixed messages so authors get a
14
+ * pointer back to their config file.
15
+ */
16
+ const SUPPORTED_RULE_NAMES = new Set([
17
+ "priority",
18
+ "weight",
19
+ "limit",
20
+ ]);
21
+ export function validateTargeting(input) {
22
+ const { agentId, engagementIds, targeting } = input;
23
+ if (engagementIds.length === 0) {
24
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": cannot validate targeting without any declared engagements`);
25
+ }
26
+ if (!targeting) {
27
+ return {
28
+ targeting: {
29
+ engagements: [{ id: engagementIds[0], rules: [] }],
30
+ },
31
+ };
32
+ }
33
+ if (!Array.isArray(targeting.engagements) || targeting.engagements.length === 0) {
34
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting.engagements must contain at least one entry`);
35
+ }
36
+ const idsSet = new Set(engagementIds);
37
+ const seen = new Set();
38
+ for (const e of targeting.engagements) {
39
+ validateEngagementEntry(agentId, e, idsSet, seen, engagementIds);
40
+ }
41
+ return { targeting };
42
+ }
43
+ function validateEngagementEntry(agentId, entry, declared, seen, declaredList) {
44
+ if (typeof entry.id !== "string" || entry.id.length === 0) {
45
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting engagement entry has empty 'id'`);
46
+ }
47
+ if (!declared.has(entry.id)) {
48
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting references engagement "${entry.id}" which is not declared (declared: ${declaredList.join(", ")})`);
49
+ }
50
+ if (seen.has(entry.id)) {
51
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting lists engagement "${entry.id}" more than once`);
52
+ }
53
+ seen.add(entry.id);
54
+ for (const rule of entry.rules ?? []) {
55
+ validateRule(agentId, entry.id, rule);
56
+ }
57
+ }
58
+ function validateRule(agentId, engagementId, rule) {
59
+ if (!rule || typeof rule !== "object") {
60
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting engagement "${engagementId}" has invalid rule ${JSON.stringify(rule)}`);
61
+ }
62
+ if (!SUPPORTED_RULE_NAMES.has(rule.name)) {
63
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting engagement "${engagementId}" has unknown rule name "${rule.name}" (supported: priority, weight, limit)`);
64
+ }
65
+ if (typeof rule.value !== "number" || !Number.isFinite(rule.value)) {
66
+ throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting engagement "${engagementId}" rule "${rule.name}" must have a numeric value`);
67
+ }
68
+ }
69
+ //# sourceMappingURL=targeting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targeting.js","sourceRoot":"","sources":["../../src/build/targeting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Command } from "commander";
2
+ export declare const DEFAULT_MARKETPLACE_URL = "https://agent-marketplace.compute.dev.ddcdragon.com";
3
+ export interface BuildProgramOptions {
4
+ /** Optional fetch override threaded into `cef publish`. Tests use this. */
5
+ fetchImpl?: typeof fetch;
6
+ /**
7
+ * How to surface unrecoverable command errors. The bin entry uses the
8
+ * default (log + process.exit(1)); tests pass a function that throws so
9
+ * vitest's `await program.parseAsync()` rejects observably.
10
+ */
11
+ onError?: (err: unknown) => never;
12
+ }
13
+ export declare function buildProgram(opts?: BuildProgramOptions): Command;
14
+ //# sourceMappingURL=cli-program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-program.d.ts","sourceRoot":"","sources":["../src/cli-program.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,uBAAuB,wDACmB,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,KAAK,CAAC;CACnC;AAQD,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CA0MpE"}