@web42/cli 0.1.15 → 0.1.17

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.
@@ -1,4 +1,4 @@
1
- import { appendFileSync, existsSync, readFileSync, writeFileSync } from "fs";
1
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2
2
  import { join } from "path";
3
3
  import { Command } from "commander";
4
4
  import chalk from "chalk";
@@ -169,6 +169,22 @@ export function makeInstallCommand(adapter) {
169
169
  const configPath = join(workspacePath, ".web42.config.json");
170
170
  writeFileSync(configPath, JSON.stringify(web42Config, null, 2) + "\n");
171
171
  spinner.stop();
172
+ const profileImageUrl = result.agent.profile_image_url;
173
+ if (profileImageUrl) {
174
+ try {
175
+ const avatarsDir = join(workspacePath, "avatars");
176
+ mkdirSync(avatarsDir, { recursive: true });
177
+ const avatarPath = join(avatarsDir, "avatar.png");
178
+ const avatarResponse = await fetch(profileImageUrl);
179
+ if (avatarResponse.ok) {
180
+ const buffer = Buffer.from(await avatarResponse.arrayBuffer());
181
+ writeFileSync(avatarPath, buffer);
182
+ }
183
+ }
184
+ catch {
185
+ // Non-fatal — avatar download failure shouldn't block install
186
+ }
187
+ }
172
188
  console.log();
173
189
  console.log(chalk.green(`Installed ${chalk.bold(`@${username}/${agentSlug}`)} as agent "${localName}"`));
174
190
  console.log(chalk.dim(` Workspace: ${workspacePath}`));
@@ -7,7 +7,7 @@ import { apiPost, apiFormData } from "../utils/api.js";
7
7
  import { requireAuth } from "../utils/config.js";
8
8
  import { openclawAdapter } from "../platforms/openclaw/adapter.js";
9
9
  import { parseSkillMd } from "../utils/skill.js";
10
- import { buildLocalSnapshot, computeHashFromSnapshot, findLocalAvatar, findAgentAvatar, readResourcesMeta, readSyncState, writeSyncState, } from "../utils/sync.js";
10
+ import { buildLocalSnapshot, computeHashFromSnapshot, findLocalAvatar, findAgentAvatar, discoverResources, readResourcesMeta, readSyncState, writeSyncState, } from "../utils/sync.js";
11
11
  function mimeFromExtension(ext) {
12
12
  const map = {
13
13
  png: "image/png",
@@ -175,10 +175,12 @@ export const pushCommand = new Command("push")
175
175
  // Step 7: Upload resources if present
176
176
  // -------------------------------------------------------------------
177
177
  const resourcesMeta = readResourcesMeta(cwd);
178
- if (resourcesMeta.length > 0) {
178
+ const discoveredResources = discoverResources(cwd);
179
+ const allResources = [...resourcesMeta, ...discoveredResources];
180
+ if (allResources.length > 0) {
179
181
  spinner.text = "Uploading resources...";
180
182
  const resForm = new FormData();
181
- const metadataForApi = resourcesMeta.map((meta, i) => ({
183
+ const metadataForApi = allResources.map((meta, i) => ({
182
184
  file_key: `resource_${i}`,
183
185
  title: meta.title,
184
186
  description: meta.description,
@@ -186,9 +188,13 @@ export const pushCommand = new Command("push")
186
188
  sort_order: meta.sort_order,
187
189
  }));
188
190
  resForm.append("metadata", JSON.stringify(metadataForApi));
189
- for (let i = 0; i < resourcesMeta.length; i++) {
190
- const meta = resourcesMeta[i];
191
- const resFilePath = join(cwd, ".web42", "resources", meta.file);
191
+ for (let i = 0; i < allResources.length; i++) {
192
+ const meta = allResources[i];
193
+ // Try .web42/resources/ first (legacy/tracked), then root resources/
194
+ let resFilePath = join(cwd, ".web42", "resources", meta.file);
195
+ if (!existsSync(resFilePath)) {
196
+ resFilePath = join(cwd, "resources", meta.file);
197
+ }
192
198
  if (existsSync(resFilePath)) {
193
199
  const resBuffer = readFileSync(resFilePath);
194
200
  const ext = meta.file.split(".").pop() ?? "";
@@ -8,6 +8,7 @@ export declare function readMarketplace(cwd: string): MarketplaceConfig;
8
8
  export declare function writeMarketplace(cwd: string, data: MarketplaceConfig): void;
9
9
  export declare function findLocalAvatar(cwd: string): string | null;
10
10
  export declare function findAgentAvatar(cwd: string): string | null;
11
+ export declare function discoverResources(cwd: string): ResourceMeta[];
11
12
  export declare function readResourcesMeta(cwd: string): ResourceMeta[];
12
13
  export declare function writeResourcesMeta(cwd: string, meta: ResourceMeta[]): void;
13
14
  export declare function buildLocalSnapshot(cwd: string): AgentSnapshot;
@@ -125,8 +125,41 @@ export function findAgentAvatar(cwd) {
125
125
  return null;
126
126
  }
127
127
  // ---------------------------------------------------------------------------
128
- // .web42/resources.json + .web42/resources/
128
+ // .web42/resources.json + .web42/resources/ + root resources/
129
129
  // ---------------------------------------------------------------------------
130
+ const RESOURCE_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "svg"];
131
+ const RESOURCE_VIDEO_EXTENSIONS = ["mp4", "webm"];
132
+ export function discoverResources(cwd) {
133
+ const resourcesDir = join(cwd, "resources");
134
+ if (!existsSync(resourcesDir))
135
+ return [];
136
+ const meta = [];
137
+ const entries = readdirSync(resourcesDir, { withFileTypes: true });
138
+ for (const entry of entries) {
139
+ if (entry.name.startsWith("."))
140
+ continue;
141
+ if (entry.isDirectory())
142
+ continue;
143
+ const ext = entry.name.split(".").pop()?.toLowerCase() || "";
144
+ let type = null;
145
+ if (RESOURCE_IMAGE_EXTENSIONS.includes(ext)) {
146
+ type = "image";
147
+ }
148
+ else if (RESOURCE_VIDEO_EXTENSIONS.includes(ext)) {
149
+ type = "video";
150
+ }
151
+ if (!type) {
152
+ throw new Error(`Unsupported file type in resources/ folder: ${entry.name}. Only images and videos are allowed.`);
153
+ }
154
+ meta.push({
155
+ file: entry.name,
156
+ title: entry.name.split(".").slice(0, -1).join("."),
157
+ type,
158
+ sort_order: meta.length,
159
+ });
160
+ }
161
+ return meta;
162
+ }
130
163
  export function readResourcesMeta(cwd) {
131
164
  const p = join(cwd, ".web42", "resources.json");
132
165
  if (!existsSync(p))
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const CLI_VERSION = "0.1.15";
1
+ export declare const CLI_VERSION = "0.1.17";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const CLI_VERSION = "0.1.15";
1
+ export const CLI_VERSION = "0.1.17";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@web42/cli",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "CLI for the Web42 Agent Marketplace - push, install, and remix OpenClaw agent packages",
5
5
  "type": "module",
6
6
  "bin": {