@cef-ai/cli 1.3.1 → 1.5.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.
- package/README.md +5 -1
- package/dist/build/load-config.d.ts +65 -4
- package/dist/build/load-config.d.ts.map +1 -1
- package/dist/build/load-config.js.map +1 -1
- package/dist/build/manifest.d.ts +103 -1
- package/dist/build/manifest.d.ts.map +1 -1
- package/dist/build/manifest.js +64 -2
- package/dist/build/manifest.js.map +1 -1
- package/dist/cli-program.d.ts +6 -0
- package/dist/cli-program.d.ts.map +1 -1
- package/dist/cli-program.js +131 -3
- package/dist/cli-program.js.map +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +113 -3
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/deploy.d.ts +38 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +317 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/init.d.ts +41 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +191 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/publish.d.ts +1 -2
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +32 -24
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/push.d.ts +31 -3
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +94 -10
- package/dist/commands/push.js.map +1 -1
- package/dist/lib/ddc.d.ts +87 -15
- package/dist/lib/ddc.d.ts.map +1 -1
- package/dist/lib/ddc.js +128 -32
- package/dist/lib/ddc.js.map +1 -1
- package/dist/lib.d.ts +4 -0
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +2 -0
- package/dist/lib.js.map +1 -1
- package/package.json +4 -3
- package/templates/hello-world/AGENTS.md +41 -0
- package/templates/hello-world/CLAUDE.md +9 -0
- package/templates/hello-world/README.md +55 -0
- package/templates/hello-world/cef.config.ts +24 -0
- package/templates/hello-world/claude/settings.json +23 -0
- package/templates/hello-world/deployments/default.jsonc +9 -0
- package/templates/hello-world/deployments/sandbox-canary.jsonc +12 -0
- package/templates/hello-world/gitignore +3 -0
- package/templates/hello-world/migrations/history/001-init.sql +5 -0
- package/templates/hello-world/package.json +23 -0
- package/templates/hello-world/src/agent.ts +44 -0
- package/templates/hello-world/test/agent.test.ts +28 -0
- package/templates/hello-world/tsconfig.json +19 -0
- package/templates/hello-world/widgets/hello/app.js +8 -0
- package/templates/hello-world/widgets/hello/hello.html +5 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type PackageManager = "pnpm" | "npm" | "yarn" | "bun";
|
|
2
|
+
export interface CefInitOptions {
|
|
3
|
+
/** Base directory the target is resolved against. Defaults to `process.cwd()`. */
|
|
4
|
+
cwd?: string;
|
|
5
|
+
/** Target directory name/path (the positional arg). Prompted when absent. */
|
|
6
|
+
dir?: string;
|
|
7
|
+
/** Agent id/alias. Defaults to a slug of the project name. */
|
|
8
|
+
name?: string;
|
|
9
|
+
/** Non-interactive: accept all defaults, never prompt. */
|
|
10
|
+
yes?: boolean;
|
|
11
|
+
/** Package manager. Defaults to detection via `npm_config_user_agent`. */
|
|
12
|
+
pm?: PackageManager;
|
|
13
|
+
/** Run `<pm> install` after scaffolding. Default `true`. */
|
|
14
|
+
install?: boolean;
|
|
15
|
+
/** `git init` + stage after scaffolding. Default `true`. */
|
|
16
|
+
git?: boolean;
|
|
17
|
+
/** Allow scaffolding into a non-empty directory. */
|
|
18
|
+
force?: boolean;
|
|
19
|
+
/** Write the AI-friendly files (AGENTS.md/CLAUDE.md/.claude). Default `true`. */
|
|
20
|
+
ai?: boolean;
|
|
21
|
+
/** Template name. Default `"hello-world"`. */
|
|
22
|
+
template?: string;
|
|
23
|
+
/** Override interactivity (tests). Defaults to `isTTY && !yes`. */
|
|
24
|
+
interactive?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface CefInitResult {
|
|
27
|
+
dir: string;
|
|
28
|
+
agentId: string;
|
|
29
|
+
projectName: string;
|
|
30
|
+
/** Destination-relative paths written, sorted. */
|
|
31
|
+
files: string[];
|
|
32
|
+
pm: PackageManager;
|
|
33
|
+
installed: boolean;
|
|
34
|
+
gitInitialized: boolean;
|
|
35
|
+
aiFiles: boolean;
|
|
36
|
+
template: string;
|
|
37
|
+
nextSteps: string[];
|
|
38
|
+
}
|
|
39
|
+
export declare function detectPackageManager(): PackageManager;
|
|
40
|
+
export declare function cefInit(opts?: CefInitOptions): Promise<CefInitResult>;
|
|
41
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,0EAA0E;IAC1E,EAAE,CAAC,EAAE,cAAc,CAAC;IACpB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4DAA4D;IAC5D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iFAAiF;IACjF,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,EAAE,EAAE,cAAc,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAyBD,wBAAgB,oBAAoB,IAAI,cAAc,CAOrD;AAuDD,wBAAsB,OAAO,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiH/E"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import * as readline from "node:readline/promises";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
/** Files allowed to pre-exist in an otherwise-"empty" target. */
|
|
9
|
+
const SAFE_FILES = new Set([
|
|
10
|
+
".git",
|
|
11
|
+
"LICENSE",
|
|
12
|
+
"LICENSE.md",
|
|
13
|
+
"README.md",
|
|
14
|
+
".gitignore",
|
|
15
|
+
]);
|
|
16
|
+
/** Top-level template entries that are omitted with `--no-ai`. */
|
|
17
|
+
const AI_TOP_LEVEL = new Set(["AGENTS.md", "CLAUDE.md", ".claude"]);
|
|
18
|
+
/** Allowed template names — restricts the value joined into the templates path. */
|
|
19
|
+
const TEMPLATE_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
20
|
+
function slugify(s) {
|
|
21
|
+
const slug = s
|
|
22
|
+
.toLowerCase()
|
|
23
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
24
|
+
.replace(/^-+|-+$/g, "");
|
|
25
|
+
return slug || "agent";
|
|
26
|
+
}
|
|
27
|
+
export function detectPackageManager() {
|
|
28
|
+
const ua = process.env.npm_config_user_agent ?? "";
|
|
29
|
+
if (ua.startsWith("pnpm"))
|
|
30
|
+
return "pnpm";
|
|
31
|
+
if (ua.startsWith("yarn"))
|
|
32
|
+
return "yarn";
|
|
33
|
+
if (ua.startsWith("bun"))
|
|
34
|
+
return "bun";
|
|
35
|
+
if (ua.startsWith("npm"))
|
|
36
|
+
return "npm";
|
|
37
|
+
return "pnpm";
|
|
38
|
+
}
|
|
39
|
+
function templatesRoot() {
|
|
40
|
+
// dist/commands/init.js → ../../templates ; src/commands/init.ts → ../../templates.
|
|
41
|
+
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
42
|
+
return path.join(dirname, "..", "..", "templates");
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Map a template-relative path to its destination. Dotfiles/dirs are stored
|
|
46
|
+
* WITHOUT a leading dot in the template (npm renames a literal `.gitignore` on
|
|
47
|
+
* publish), and re-dotted here.
|
|
48
|
+
*/
|
|
49
|
+
function mapDest(rel) {
|
|
50
|
+
return rel
|
|
51
|
+
.split(path.sep)
|
|
52
|
+
.map((seg) => seg === "gitignore" ? ".gitignore" : seg === "claude" ? ".claude" : seg)
|
|
53
|
+
.join(path.sep);
|
|
54
|
+
}
|
|
55
|
+
function substitute(content, vars) {
|
|
56
|
+
return content.replace(/\{\{(\w+)\}\}/g, (m, k) => (k in vars ? vars[k] : m));
|
|
57
|
+
}
|
|
58
|
+
async function walk(dir, base = dir) {
|
|
59
|
+
const out = [];
|
|
60
|
+
for (const entry of await fs.readdir(dir, { withFileTypes: true })) {
|
|
61
|
+
const full = path.join(dir, entry.name);
|
|
62
|
+
if (entry.isDirectory())
|
|
63
|
+
out.push(...(await walk(full, base)));
|
|
64
|
+
else
|
|
65
|
+
out.push(path.relative(base, full));
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
async function nonEmptyUnsafeEntries(dir) {
|
|
70
|
+
let entries;
|
|
71
|
+
try {
|
|
72
|
+
entries = await fs.readdir(dir);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return []; // does not exist yet → fine
|
|
76
|
+
}
|
|
77
|
+
return entries.filter((e) => !SAFE_FILES.has(e));
|
|
78
|
+
}
|
|
79
|
+
async function insideGitRepo(dir) {
|
|
80
|
+
try {
|
|
81
|
+
await execFileAsync("git", ["rev-parse", "--is-inside-work-tree"], { cwd: dir });
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export async function cefInit(opts = {}) {
|
|
89
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
90
|
+
const interactive = opts.interactive ?? (Boolean(process.stdin.isTTY) && !opts.yes);
|
|
91
|
+
let rl;
|
|
92
|
+
const ask = async (q, def) => {
|
|
93
|
+
if (!interactive)
|
|
94
|
+
return def;
|
|
95
|
+
rl ??= readline.createInterface({
|
|
96
|
+
input: process.stdin,
|
|
97
|
+
output: process.stdout,
|
|
98
|
+
});
|
|
99
|
+
const answer = (await rl.question(`${q} (${def}) `)).trim();
|
|
100
|
+
return answer || def;
|
|
101
|
+
};
|
|
102
|
+
try {
|
|
103
|
+
const dirName = opts.dir ?? (await ask("Project directory", "my-agent"));
|
|
104
|
+
const targetDir = path.resolve(cwd, dirName);
|
|
105
|
+
const projectName = path.basename(targetDir);
|
|
106
|
+
const agentId = slugify(opts.name ?? (await ask("Agent id", slugify(projectName))));
|
|
107
|
+
const pm = opts.pm ?? detectPackageManager();
|
|
108
|
+
const template = opts.template ?? "hello-world";
|
|
109
|
+
const ai = opts.ai ?? true;
|
|
110
|
+
const doInstall = opts.install ?? true;
|
|
111
|
+
const doGit = opts.git ?? true;
|
|
112
|
+
const unsafe = await nonEmptyUnsafeEntries(targetDir);
|
|
113
|
+
if (unsafe.length > 0 && !opts.force) {
|
|
114
|
+
const shown = unsafe.slice(0, 5).join(", ");
|
|
115
|
+
throw new Error(`[cef init] target directory "${targetDir}" is not empty ` +
|
|
116
|
+
`(${shown}${unsafe.length > 5 ? ", …" : ""}). ` +
|
|
117
|
+
`Use --force to scaffold into it anyway.`);
|
|
118
|
+
}
|
|
119
|
+
// Guard the template name before joining it into a path — a value like
|
|
120
|
+
// "../../etc" would otherwise escape the templates dir (path traversal).
|
|
121
|
+
if (!TEMPLATE_RE.test(template)) {
|
|
122
|
+
throw new Error(`[cef init] invalid template name "${template}" (must match ${TEMPLATE_RE})`);
|
|
123
|
+
}
|
|
124
|
+
const srcRoot = path.join(templatesRoot(), template);
|
|
125
|
+
try {
|
|
126
|
+
await fs.access(srcRoot);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
throw new Error(`[cef init] unknown template "${template}"`);
|
|
130
|
+
}
|
|
131
|
+
const vars = { projectName, agentId };
|
|
132
|
+
const written = [];
|
|
133
|
+
for (const rel of await walk(srcRoot)) {
|
|
134
|
+
const dest = mapDest(rel);
|
|
135
|
+
const topSeg = dest.split(path.sep)[0];
|
|
136
|
+
if (!ai && AI_TOP_LEVEL.has(topSeg))
|
|
137
|
+
continue;
|
|
138
|
+
const destFile = path.join(targetDir, dest);
|
|
139
|
+
await fs.mkdir(path.dirname(destFile), { recursive: true });
|
|
140
|
+
const raw = await fs.readFile(path.join(srcRoot, rel), "utf8");
|
|
141
|
+
await fs.writeFile(destFile, substitute(raw, vars));
|
|
142
|
+
written.push(dest);
|
|
143
|
+
}
|
|
144
|
+
let gitInitialized = false;
|
|
145
|
+
if (doGit && !(await insideGitRepo(targetDir))) {
|
|
146
|
+
try {
|
|
147
|
+
await execFileAsync("git", ["init", "-q"], { cwd: targetDir });
|
|
148
|
+
await execFileAsync("git", ["add", "-A"], { cwd: targetDir });
|
|
149
|
+
gitInitialized = true;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
gitInitialized = false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
let installed = false;
|
|
156
|
+
if (doInstall) {
|
|
157
|
+
try {
|
|
158
|
+
await execFileAsync(pm, ["install"], { cwd: targetDir });
|
|
159
|
+
installed = true;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
installed = false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const relDir = path.relative(cwd, targetDir) || ".";
|
|
166
|
+
const nextSteps = [
|
|
167
|
+
`cd ${relDir}`,
|
|
168
|
+
...(installed ? [] : [`${pm} install`]),
|
|
169
|
+
`${pm} test`,
|
|
170
|
+
`${pm} run build`,
|
|
171
|
+
`${pm} run push # needs a DDC bucket + --as-pubkey (see: cef push --help)`,
|
|
172
|
+
`# then deploy in ROC (create/select your Agent Service → Deploy)`,
|
|
173
|
+
];
|
|
174
|
+
return {
|
|
175
|
+
dir: targetDir,
|
|
176
|
+
agentId,
|
|
177
|
+
projectName,
|
|
178
|
+
files: written.sort(),
|
|
179
|
+
pm,
|
|
180
|
+
installed,
|
|
181
|
+
gitInitialized,
|
|
182
|
+
aiFiles: ai,
|
|
183
|
+
template,
|
|
184
|
+
nextSteps,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
rl?.close();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,8 +42,7 @@ export interface CefPublishResult {
|
|
|
42
42
|
/** Whatever `agentId` the marketplace returned (plain alias today). */
|
|
43
43
|
agentId: string;
|
|
44
44
|
version: string;
|
|
45
|
-
|
|
46
|
-
/** Pubkey the manifest was published as (hex). */
|
|
45
|
+
/** Pubkey the card was published as (hex). */
|
|
47
46
|
pubkey: string;
|
|
48
47
|
}
|
|
49
48
|
export declare function cefPublish(opts: CefPublishOptions): Promise<CefPublishResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAsCA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC/B,MAAM,uBAAuB,CAAC;AAI/B,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,cAAc,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,CACvB,IAAI,EAAE,yBAAyB,KAC5B,OAAO,CAAC,aAAa,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;CAChB;AAgCD,wBAAsB,UAAU,CAC9B,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAwI3B"}
|
package/dist/commands/publish.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `cef publish` — POSTs a built agent's
|
|
2
|
+
* `cef publish` — POSTs a built agent's CARD to the CEF marketplace.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* The marketplace is card-only: it stores just the agent card for discovery.
|
|
5
|
+
* The full manifest already lives in the DDC bucket registry (written by
|
|
6
|
+
* `cef push`) and is never sent to, hashed by, or stored by the marketplace.
|
|
7
|
+
*
|
|
8
|
+
* Wire contract:
|
|
5
9
|
*
|
|
6
10
|
* POST <marketplaceUrl>/api/v1/marketplace/agents
|
|
7
11
|
* Headers:
|
|
@@ -10,19 +14,23 @@
|
|
|
10
14
|
* X-AS-Signature: <hex Ed25519 signature over canonical body bytes>
|
|
11
15
|
* Body (JCS-canonicalized JSON):
|
|
12
16
|
* {
|
|
13
|
-
* agentId:
|
|
14
|
-
* version:
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
17
|
+
* agentId: <composite "<asPubKey>:<alias>">,
|
|
18
|
+
* version: <semver>,
|
|
19
|
+
* agentServicePubkey: <hex; on-platform AS pubkey>,
|
|
20
|
+
* card: <the AgentCard object ONLY — name, description,
|
|
21
|
+
* iconUrl?, capabilities?, category?, tags?, …>,
|
|
22
|
+
* issuedAt: <ISO 8601>,
|
|
23
|
+
* nonce: <base64url 16 random bytes>
|
|
18
24
|
* }
|
|
19
25
|
*
|
|
26
|
+
* Response 201 JSON: { agentId, version } (nothing manifest-derived).
|
|
27
|
+
*
|
|
20
28
|
* `cef build` emits the manifest with `agentId` / `agentServicePubkey` left
|
|
21
|
-
* as empty strings; this command
|
|
22
|
-
* for `agentId`, the loaded AS pubkey for `agentServicePubkey`)
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
29
|
+
* as empty strings; this command resolves them (composite `<asPubKey>:<alias>`
|
|
30
|
+
* for `agentId`, the loaded AS pubkey for `agentServicePubkey`) and extracts
|
|
31
|
+
* `manifest.card` for the body before signing the envelope. Vault enforces
|
|
32
|
+
* the `<asPubKey>:` prefix on connect, so the canonical form is composite —
|
|
33
|
+
* the plain alias is recorded only in the manifest (in the DDC registry).
|
|
26
34
|
*/
|
|
27
35
|
import crypto from "node:crypto";
|
|
28
36
|
import fs from "node:fs/promises";
|
|
@@ -65,7 +73,10 @@ export async function cefPublish(opts) {
|
|
|
65
73
|
// The plain alias is the wire identity. `cef build` writes it to
|
|
66
74
|
// `manifest.alias` (per `prototype.md` §"AgentManifest.Alias") and
|
|
67
75
|
// leaves `manifest.agentId` blank for `cef publish` to fill in.
|
|
68
|
-
|
|
76
|
+
// Prefer the plain alias; if only the composite `agentId`
|
|
77
|
+
// (`<asPubkey>:<alias>`) is present, take the tail so re-composing the
|
|
78
|
+
// agentId below doesn't double the pubkey.
|
|
79
|
+
const alias = (manifest.alias ?? manifest.agentId?.split(":").pop());
|
|
69
80
|
const resolver = opts.resolveCredentialsImpl ?? resolveCredentials;
|
|
70
81
|
const credResolveOpts = {
|
|
71
82
|
...(opts.privkey !== undefined ? { privkeyFlag: opts.privkey } : {}),
|
|
@@ -99,15 +110,15 @@ export async function cefPublish(opts) {
|
|
|
99
110
|
? (explicitAsPubkey ?? cleanPubkey).slice(2)
|
|
100
111
|
: (explicitAsPubkey ?? cleanPubkey);
|
|
101
112
|
const compositeAgentId = `${asPubkey}:${alias}`;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
};
|
|
113
|
+
// Card-only wire body. The full manifest stays in the DDC bucket registry
|
|
114
|
+
// (written by `cef push`); the marketplace only stores the card for
|
|
115
|
+
// discovery. Sign the SAME envelope (headers, issuedAt, nonce) — only the
|
|
116
|
+
// body shape changed from `manifest` to `card`.
|
|
107
117
|
const body = {
|
|
108
118
|
agentId: compositeAgentId,
|
|
109
|
-
version:
|
|
110
|
-
|
|
119
|
+
version: manifest.version,
|
|
120
|
+
agentServicePubkey: asPubkey,
|
|
121
|
+
card: manifest.card,
|
|
111
122
|
issuedAt: new Date().toISOString(),
|
|
112
123
|
nonce: randomBase64UrlNonce(16),
|
|
113
124
|
};
|
|
@@ -125,15 +136,12 @@ export async function cefPublish(opts) {
|
|
|
125
136
|
});
|
|
126
137
|
if (res.status === 201) {
|
|
127
138
|
const json = (await res.json());
|
|
128
|
-
if (typeof json.agentId !== "string" ||
|
|
129
|
-
typeof json.version !== "string" ||
|
|
130
|
-
typeof json.manifestCid !== "string") {
|
|
139
|
+
if (typeof json.agentId !== "string" || typeof json.version !== "string") {
|
|
131
140
|
throw new Error(`[cef publish] unexpected 201 body: ${JSON.stringify(json)}`);
|
|
132
141
|
}
|
|
133
142
|
return {
|
|
134
143
|
agentId: json.agentId,
|
|
135
144
|
version: json.version,
|
|
136
|
-
manifestCid: json.manifestCid,
|
|
137
145
|
pubkey,
|
|
138
146
|
};
|
|
139
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/push.d.ts
CHANGED
|
@@ -9,13 +9,33 @@ export interface CefPushOptions {
|
|
|
9
9
|
bucket: number | bigint | string;
|
|
10
10
|
/**
|
|
11
11
|
* Substrate secret phrase (Sr25519) for the DDC bucket owner. Falls back to
|
|
12
|
-
* `$CEF_DDC_SECRET_PHRASE` when omitted.
|
|
12
|
+
* `$CEF_DDC_SECRET_PHRASE` when omitted. Mutually exclusive with
|
|
13
|
+
* `accessToken` — provide exactly one.
|
|
13
14
|
*/
|
|
14
15
|
secretPhrase?: string;
|
|
16
|
+
/**
|
|
17
|
+
* DDC access token (base58) authorizing writes to the bucket, granted by the
|
|
18
|
+
* bucket owner. Falls back to `$CEF_DDC_ACCESS_TOKEN`. Use this when you don't
|
|
19
|
+
* hold the bucket's secret phrase — e.g. a token generated in ROC by the
|
|
20
|
+
* wallet that owns the Agent Service's bucket. Mutually exclusive with
|
|
21
|
+
* `secretPhrase`.
|
|
22
|
+
*/
|
|
23
|
+
accessToken?: string;
|
|
15
24
|
/** Network preset (MAINNET/TESTNET/DEVNET). Defaults to MAINNET. */
|
|
16
25
|
preset?: DdcPreset;
|
|
17
26
|
/** Explicit blockchain endpoint (overrides `preset`). */
|
|
18
27
|
endpoint?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Agent Service pubkey (hex, exactly as shown in ROC) to stamp into the
|
|
30
|
+
* pushed manifest's identity. `cef push` signs DDC writes with an unrelated
|
|
31
|
+
* bucket-owner key — the signing keypair can be anything with write access —
|
|
32
|
+
* so the AS identity cannot be derived and must be passed in. When set, the
|
|
33
|
+
* manifest's `agentServicePubkey` and `agentId` (`<asPubkey>:<alias>`) are
|
|
34
|
+
* stamped before upload, so bucket consumers (the dashboard registry read,
|
|
35
|
+
* the vault-api connect check) see a fully-identified manifest immediately,
|
|
36
|
+
* without waiting for `cef publish`.
|
|
37
|
+
*/
|
|
38
|
+
agentServicePubkey?: string;
|
|
19
39
|
/** Optional CDN endpoint override. */
|
|
20
40
|
cdn?: string;
|
|
21
41
|
/** Output directory the build wrote to. Defaults to `<cwd>/dist`. */
|
|
@@ -32,12 +52,20 @@ export interface CefPushResult {
|
|
|
32
52
|
bucketId: string;
|
|
33
53
|
/** LEAF `bundle.js` piece CID stamped into `manifest.bundle.cid`. */
|
|
34
54
|
cid: string;
|
|
35
|
-
/**
|
|
55
|
+
/** LEAF `manifest.json` piece CID stored inside the version node. */
|
|
56
|
+
manifestCid: string;
|
|
57
|
+
/** Per-version DAG CID (links bundle.js + manifest.json + widgets/). */
|
|
36
58
|
versionCid: string;
|
|
37
59
|
/** Per-agent record DAG CID. */
|
|
38
60
|
recordCid: string;
|
|
39
|
-
/** `agents` directory DAG CID (the
|
|
61
|
+
/** `agents` directory DAG CID (the CNS target). */
|
|
40
62
|
directoryCid: string;
|
|
63
|
+
/** One entry per widget linked under the version node's `widgets/` (empty when none). */
|
|
64
|
+
widgets: Array<{
|
|
65
|
+
id: string;
|
|
66
|
+
dirCid: string;
|
|
67
|
+
fileCount: number;
|
|
68
|
+
}>;
|
|
41
69
|
}
|
|
42
70
|
export declare function cefPush(opts: CefPushOptions): Promise<CefPushResult>;
|
|
43
71
|
//# sourceMappingURL=push.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAmBA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,SAAS,EAEf,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAmBA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,SAAS,EAEf,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,aAAa,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,yFAAyF;IACzF,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnE;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CA4I1E"}
|
package/dist/commands/push.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import fs from "node:fs/promises";
|
|
17
17
|
import path from "node:path";
|
|
18
|
-
import {
|
|
18
|
+
import { pushAgentVersion, } from "../lib/ddc.js";
|
|
19
19
|
const DEFAULT_DIST = "dist";
|
|
20
20
|
export async function cefPush(opts) {
|
|
21
21
|
const cwd = opts.cwd ? path.resolve(opts.cwd) : process.cwd();
|
|
@@ -23,10 +23,20 @@ export async function cefPush(opts) {
|
|
|
23
23
|
? path.resolve(cwd, opts.distDir)
|
|
24
24
|
: path.join(cwd, DEFAULT_DIST);
|
|
25
25
|
const bucketId = parseBucketId(opts.bucket);
|
|
26
|
+
// Auth: either the bucket owner's secret phrase or an access token minted by
|
|
27
|
+
// that owner. Exactly one — a token lets you push to a bucket whose seed you
|
|
28
|
+
// don't hold (e.g. one generated in ROC by the AS bucket's owner wallet).
|
|
26
29
|
const secretPhrase = opts.secretPhrase ?? process.env.CEF_DDC_SECRET_PHRASE;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
const accessToken = opts.accessToken ?? process.env.CEF_DDC_ACCESS_TOKEN;
|
|
31
|
+
const hasPhrase = !!secretPhrase && secretPhrase.trim().length > 0;
|
|
32
|
+
const hasToken = !!accessToken && accessToken.trim().length > 0;
|
|
33
|
+
if (!hasPhrase && !hasToken) {
|
|
34
|
+
throw new Error("[cef push] no DDC authorization — provide one of:\n"
|
|
35
|
+
+ " --secret-phrase / $CEF_DDC_SECRET_PHRASE (the Sr25519 phrase that owns the bucket)\n"
|
|
36
|
+
+ " --access-token / $CEF_DDC_ACCESS_TOKEN (a token granted by the bucket owner)");
|
|
37
|
+
}
|
|
38
|
+
if (hasPhrase && hasToken) {
|
|
39
|
+
throw new Error("[cef push] both --secret-phrase and --access-token were provided — pass exactly one.");
|
|
30
40
|
}
|
|
31
41
|
const agentId = opts.agentId ?? (await autodetectAgentId(distDir));
|
|
32
42
|
const agentDir = path.join(distDir, agentId);
|
|
@@ -49,12 +59,58 @@ export async function cefPush(opts) {
|
|
|
49
59
|
if (!version) {
|
|
50
60
|
throw new Error(`[cef push] manifest at ${manifestPath} has no version — run \`cef build\` first`);
|
|
51
61
|
}
|
|
52
|
-
|
|
62
|
+
// Gather each declared widget's staged directory (dist/<id>/widgets/<id>/)
|
|
63
|
+
// BEFORE upload — missing/empty dirs warn and are dropped so their manifest
|
|
64
|
+
// entry keeps its placeholder dag (and is not linked under the version node).
|
|
65
|
+
const widgetUploads = [];
|
|
66
|
+
for (const widget of manifest.widgets ?? []) {
|
|
67
|
+
const widgetDir = path.join(agentDir, "widgets", widget.id);
|
|
68
|
+
const files = await readWidgetFiles(widgetDir);
|
|
69
|
+
if (files === null) {
|
|
70
|
+
console.warn(`[cef push] WARNING: widget "${widget.id}": no staged directory at ${widgetDir} — `
|
|
71
|
+
+ `skipping (run \`cef build\` after the agent's build:widgets step).`);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (files.length === 0) {
|
|
75
|
+
console.warn(`[cef push] WARNING: widget "${widget.id}": staged directory ${widgetDir} is empty — skipping.`);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
widgetUploads.push({ id: widget.id, files });
|
|
79
|
+
}
|
|
80
|
+
// The bytes we upload AND write to disk — captured from the stamping callback
|
|
81
|
+
// so the on-disk manifest.json matches the one stored in the version node.
|
|
82
|
+
let finalManifestBytes = "";
|
|
83
|
+
const result = await pushAgentVersion({
|
|
53
84
|
bucketId,
|
|
54
85
|
agentName,
|
|
55
86
|
version,
|
|
56
87
|
bundleBytes,
|
|
57
|
-
|
|
88
|
+
widgets: widgetUploads,
|
|
89
|
+
// Stamp the content-addressed refs into the manifest BEFORE it is stored,
|
|
90
|
+
// so the version node's manifest.json carries them. bucketId is recorded as
|
|
91
|
+
// a DECIMAL STRING per the locked contract.
|
|
92
|
+
buildManifestBytes: ({ bundleCid, widgets }) => {
|
|
93
|
+
manifest.bundle = { bucketId: bucketId.toString(), cid: bundleCid };
|
|
94
|
+
for (const w of widgets) {
|
|
95
|
+
const decl = (manifest.widgets ?? []).find((x) => x.id === w.id);
|
|
96
|
+
if (decl)
|
|
97
|
+
decl.dag = { bucketId: bucketId.toString(), cid: w.dirCid };
|
|
98
|
+
}
|
|
99
|
+
// Stamp the AS identity when provided. `cef build` leaves agentId /
|
|
100
|
+
// agentServicePubkey empty (they're filled at publish), but push targets
|
|
101
|
+
// a known agent service, so stamp them here from the supplied AS pubkey
|
|
102
|
+
// — the manifest's `agentId` is `<asPubkey>:<alias>`, matching what ROC,
|
|
103
|
+
// the dashboard registry, and the vault-api connect check expect.
|
|
104
|
+
const asPub = opts.agentServicePubkey?.trim();
|
|
105
|
+
if (asPub) {
|
|
106
|
+
manifest.agentServicePubkey = asPub;
|
|
107
|
+
manifest.agentId = `${asPub}:${manifest.alias || agentName}`;
|
|
108
|
+
}
|
|
109
|
+
finalManifestBytes = JSON.stringify(manifest, null, 2) + "\n";
|
|
110
|
+
return new TextEncoder().encode(finalManifestBytes);
|
|
111
|
+
},
|
|
112
|
+
...(hasPhrase ? { secretPhrase } : {}),
|
|
113
|
+
...(hasToken ? { accessToken } : {}),
|
|
58
114
|
...(opts.preset !== undefined ? { preset: opts.preset } : {}),
|
|
59
115
|
...(opts.endpoint !== undefined ? { endpoint: opts.endpoint } : {}),
|
|
60
116
|
...(opts.cdn !== undefined ? { cdn: opts.cdn } : {}),
|
|
@@ -62,19 +118,47 @@ export async function cefPush(opts) {
|
|
|
62
118
|
? { ddcModuleImpl: opts.ddcModuleImpl }
|
|
63
119
|
: {}),
|
|
64
120
|
});
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
121
|
+
for (const w of result.widgets) {
|
|
122
|
+
console.log(` widget ${w.id}: dir DAG ${w.dirCid} (${w.fileCount} file${w.fileCount === 1 ? "" : "s"})`);
|
|
123
|
+
}
|
|
124
|
+
// Write the stamped manifest back once (identical bytes to the version node).
|
|
125
|
+
await fs.writeFile(manifestPath, finalManifestBytes, "utf8");
|
|
69
126
|
return {
|
|
70
127
|
agentId,
|
|
71
128
|
bucketId: bucketId.toString(),
|
|
72
129
|
cid: result.leafCid,
|
|
130
|
+
manifestCid: result.manifestCid,
|
|
73
131
|
versionCid: result.versionCid,
|
|
74
132
|
recordCid: result.recordCid,
|
|
75
133
|
directoryCid: result.directoryCid,
|
|
134
|
+
widgets: result.widgets,
|
|
76
135
|
};
|
|
77
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Read every file directly under a staged widget directory as
|
|
139
|
+
* `{ name: basename, bytes }`. Flat listing (entry + siblings). Returns
|
|
140
|
+
* `null` when the directory does not exist (widget not staged), or `[]` when
|
|
141
|
+
* it exists but contains no files.
|
|
142
|
+
*/
|
|
143
|
+
async function readWidgetFiles(widgetDir) {
|
|
144
|
+
let entries;
|
|
145
|
+
try {
|
|
146
|
+
entries = await fs.readdir(widgetDir, { withFileTypes: true });
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
if (e.code === "ENOENT")
|
|
150
|
+
return null;
|
|
151
|
+
throw e;
|
|
152
|
+
}
|
|
153
|
+
const files = [];
|
|
154
|
+
for (const entry of entries) {
|
|
155
|
+
if (!entry.isFile())
|
|
156
|
+
continue;
|
|
157
|
+
const bytes = await fs.readFile(path.join(widgetDir, entry.name));
|
|
158
|
+
files.push({ name: entry.name, bytes });
|
|
159
|
+
}
|
|
160
|
+
return files;
|
|
161
|
+
}
|
|
78
162
|
function parseBucketId(bucket) {
|
|
79
163
|
if (typeof bucket === "bigint")
|
|
80
164
|
return bucket;
|