@web42/cli 0.1.14 → 0.1.16

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.
@@ -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",
@@ -24,6 +24,7 @@ function mimeFromExtension(ext) {
24
24
  export const pushCommand = new Command("push")
25
25
  .description("Push your agent package to the Web42 marketplace")
26
26
  .option("--force", "Skip hash comparison and always push")
27
+ .option("--force-avatar", "Explicitly upload avatar even if no other changes")
27
28
  .action(async (opts) => {
28
29
  const config = requireAuth();
29
30
  const cwd = process.cwd();
@@ -141,7 +142,7 @@ export const pushCommand = new Command("push")
141
142
  // -----------------------------------------------------------------------
142
143
  // Step 4: Compare local hash with last known local hash (unless --force)
143
144
  // -----------------------------------------------------------------------
144
- if (!opts.force && !isCreated && syncState?.last_local_hash) {
145
+ if (!opts.force && !opts.forceAvatar && !isCreated && syncState?.last_local_hash) {
145
146
  if (localHash === syncState.last_local_hash) {
146
147
  spinner.succeed(`${chalk.bold(`@${config.username}/${manifest.name}`)} has no local changes since last sync.`);
147
148
  return;
@@ -174,10 +175,12 @@ export const pushCommand = new Command("push")
174
175
  // Step 7: Upload resources if present
175
176
  // -------------------------------------------------------------------
176
177
  const resourcesMeta = readResourcesMeta(cwd);
177
- if (resourcesMeta.length > 0) {
178
+ const discoveredResources = discoverResources(cwd);
179
+ const allResources = [...resourcesMeta, ...discoveredResources];
180
+ if (allResources.length > 0) {
178
181
  spinner.text = "Uploading resources...";
179
182
  const resForm = new FormData();
180
- const metadataForApi = resourcesMeta.map((meta, i) => ({
183
+ const metadataForApi = allResources.map((meta, i) => ({
181
184
  file_key: `resource_${i}`,
182
185
  title: meta.title,
183
186
  description: meta.description,
@@ -185,9 +188,13 @@ export const pushCommand = new Command("push")
185
188
  sort_order: meta.sort_order,
186
189
  }));
187
190
  resForm.append("metadata", JSON.stringify(metadataForApi));
188
- for (let i = 0; i < resourcesMeta.length; i++) {
189
- const meta = resourcesMeta[i];
190
- 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
+ }
191
198
  if (existsSync(resFilePath)) {
192
199
  const resBuffer = readFileSync(resFilePath);
193
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.14";
1
+ export declare const CLI_VERSION = "0.1.16";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const CLI_VERSION = "0.1.14";
1
+ export const CLI_VERSION = "0.1.16";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@web42/cli",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "CLI for the Web42 Agent Marketplace - push, install, and remix OpenClaw agent packages",
5
5
  "type": "module",
6
6
  "bin": {