clawon 0.1.13 → 0.1.15

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 (2) hide show
  1. package/dist/index.js +88 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -41,7 +41,15 @@ async function api(baseUrl, endpoint, method, apiKey, body) {
41
41
  body: body ? JSON.stringify(body) : void 0
42
42
  });
43
43
  const json = await res.json().catch(() => ({}));
44
- if (!res.ok) throw new Error(json.error || json.message || `HTTP ${res.status}`);
44
+ if (!res.ok) {
45
+ if (json.upgradeRequired) {
46
+ console.error(`
47
+ \u2717 ${json.error || "This feature requires a paid plan."}`);
48
+ console.error(" Upgrade at: https://clawon.io/dashboard/billing");
49
+ process.exit(1);
50
+ }
51
+ throw new Error(json.error || json.message || `HTTP ${res.status}`);
52
+ }
45
53
  return json;
46
54
  }
47
55
  var INCLUDE_PATTERNS = [
@@ -275,14 +283,6 @@ program.command("login").description("Connect to Clawon with your API key").opti
275
283
  }
276
284
  });
277
285
  program.command("backup").description("Backup your OpenClaw workspace to the cloud").option("--dry-run", "Show what would be backed up without uploading").option("--tag <label>", "Add a label to this backup").option("--include-memory-db", "Include SQLite memory index").option("--include-sessions", "Include chat history (sessions)").option("--scheduled", "Internal: triggered by cron (suppresses interactive output)").action(async (opts) => {
278
- if (opts.includeMemoryDb) {
279
- console.error("\u2717 Memory DB cloud backup requires a Hobby or Pro account. Use `clawon local backup --include-memory-db` for local backups.");
280
- process.exit(1);
281
- }
282
- if (opts.includeSessions) {
283
- console.error("\u2717 Session backup requires a Hobby or Pro account. Use `clawon local backup --include-sessions` for local backups.");
284
- process.exit(1);
285
- }
286
286
  const cfg = readConfig();
287
287
  if (!cfg) {
288
288
  console.error("\u2717 Not logged in. Run: clawon login --api-key <key>");
@@ -298,7 +298,7 @@ program.command("backup").description("Backup your OpenClaw workspace to the clo
298
298
  process.exit(1);
299
299
  }
300
300
  console.log("Discovering files...");
301
- const files = discoverFiles(OPENCLAW_DIR);
301
+ const files = discoverFiles(OPENCLAW_DIR, !!opts.includeMemoryDb, !!opts.includeSessions);
302
302
  if (files.length === 0) {
303
303
  console.error("\u2717 No files found to backup");
304
304
  process.exit(1);
@@ -373,10 +373,11 @@ program.command("backup").description("Backup your OpenClaw workspace to the clo
373
373
  trackCliEvent(cfg.profileId, "scheduled_backup_failed", { type: "cloud", error: msg });
374
374
  }
375
375
  if (msg.includes("Snapshot limit")) {
376
- console.error("\n\u2717 Snapshot limit reached (2).");
376
+ console.error("\n\u2717 Snapshot limit reached.");
377
377
  console.error(" Delete one first: clawon delete <id>");
378
378
  console.error(" Delete oldest: clawon delete --oldest");
379
379
  console.error(" List snapshots: clawon list");
380
+ console.error(" Upgrade plan: https://clawon.io/dashboard/billing");
380
381
  } else {
381
382
  console.error(`
382
383
  \u2717 Backup failed: ${msg}`);
@@ -616,13 +617,51 @@ var schedule = program.command("schedule").description("Manage scheduled cloud b
616
617
  schedule.command("on").description("Enable scheduled cloud backups via cron").option("--every <interval>", "Backup interval: 1h, 6h, 12h, 24h", "12h").action(async (opts) => {
617
618
  assertNotWindows();
618
619
  const cfg = readConfig();
619
- trackCliEvent(cfg?.profileId || "anonymous", "schedule_enabled_attempted", {
620
+ if (!cfg) {
621
+ console.error("\u2717 Not logged in. Run: clawon login --api-key <key>");
622
+ process.exit(1);
623
+ }
624
+ const interval = opts.every;
625
+ if (!VALID_INTERVALS.includes(interval)) {
626
+ console.error(`\u2717 Invalid interval: ${interval}. Valid options: ${VALID_INTERVALS.join(", ")}`);
627
+ process.exit(1);
628
+ }
629
+ try {
630
+ const data = await api(
631
+ cfg.apiBaseUrl || "https://clawon.io",
632
+ `/api/v1/profile/status?profileId=${cfg.profileId}`,
633
+ "GET",
634
+ cfg.apiKey
635
+ );
636
+ const limits = data.tierLimits || {};
637
+ if (!limits.scheduledCloud) {
638
+ console.error("\u2717 Scheduled cloud backups require a Hobby or Pro plan.");
639
+ console.error(" Use `clawon local schedule on` for free local scheduled backups.");
640
+ console.error(" Upgrade at: https://clawon.io/dashboard/billing");
641
+ process.exit(1);
642
+ }
643
+ } catch (e) {
644
+ console.error(`\u2717 Failed to check plan: ${e.message}`);
645
+ process.exit(1);
646
+ }
647
+ const cronExpr = INTERVAL_CRON[interval];
648
+ const command = resolveCliCommand(`backup --scheduled`);
649
+ addCronEntry(CRON_MARKER_CLOUD, cronExpr, command);
650
+ updateConfig({
651
+ schedule: {
652
+ cloud: {
653
+ enabled: true,
654
+ intervalHours: parseInt(interval)
655
+ }
656
+ }
657
+ });
658
+ console.log(`\u2713 Scheduled cloud backup enabled`);
659
+ console.log(` Interval: every ${interval}`);
660
+ console.log(` Log: ${SCHEDULE_LOG}`);
661
+ trackCliEvent(cfg.profileId, "schedule_enabled", {
620
662
  type: "cloud",
621
- interval_hours: parseInt(opts.every),
622
- gated: true
663
+ interval_hours: parseInt(interval)
623
664
  });
624
- console.error("\u2717 Scheduled cloud backups require a Hobby or Pro account. Use `clawon local schedule on` for local scheduled backups.");
625
- process.exit(1);
626
665
  });
627
666
  schedule.command("off").description("Disable scheduled cloud backups").action(async () => {
628
667
  assertNotWindows();
@@ -1108,6 +1147,39 @@ program.command("status").description("Show current status").action(async () =>
1108
1147
  }
1109
1148
  trackCliEvent(cfg?.profileId || "anonymous", "cli_status_viewed");
1110
1149
  });
1150
+ program.command("plan").description("Show your current plan, limits, and usage").action(async () => {
1151
+ const cfg = readConfig();
1152
+ if (!cfg) {
1153
+ console.error("\u2717 Not logged in. Run: clawon login --api-key <key>");
1154
+ process.exit(1);
1155
+ }
1156
+ try {
1157
+ const data = await api(
1158
+ cfg.apiBaseUrl || "https://clawon.io",
1159
+ `/api/v1/profile/status?profileId=${cfg.profileId}${cfg.workspaceId ? `&workspaceId=${cfg.workspaceId}` : ""}`,
1160
+ "GET",
1161
+ cfg.apiKey
1162
+ );
1163
+ const tier = data.tier || "free";
1164
+ const limits = data.tierLimits || {};
1165
+ const label = limits.label || "Starter";
1166
+ console.log(`
1167
+ Plan: ${label} (${tier})`);
1168
+ console.log(` Snapshots: ${limits.snapshotLimit || 2} per workspace`);
1169
+ console.log(` Workspaces: ${limits.workspaceLimit || 1}`);
1170
+ console.log(` Max size: ${limits.maxSizeMb || 50} MB`);
1171
+ console.log(` Memory DB: ${limits.includeMemoryDb ? "included" : "not included (Hobby+)"}`);
1172
+ console.log(` Sessions: ${limits.includeSessions ? "included" : "not included (Hobby+)"}`);
1173
+ console.log(` Cloud schedule: ${limits.scheduledCloud ? "available" : "not available (Hobby+)"}`);
1174
+ console.log(`
1175
+ Manage: https://clawon.io/dashboard/billing
1176
+ `);
1177
+ trackCliEvent(cfg.profileId, "cli_plan_checked", { tier });
1178
+ } catch (e) {
1179
+ console.error(`\u2717 Failed to fetch plan: ${e.message}`);
1180
+ process.exit(1);
1181
+ }
1182
+ });
1111
1183
  program.command("logout").description("Remove local credentials").action(() => {
1112
1184
  const cfg = readConfig();
1113
1185
  if (fs.existsSync(CONFIG_PATH)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawon",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Backup and restore your OpenClaw workspace",
5
5
  "type": "module",
6
6
  "bin": {