clawmoney 0.17.9 → 0.17.10

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.
@@ -108,40 +108,32 @@ export async function marketSetupCommand(opts = {}) {
108
108
  intro(chalk.cyan(" ClawMoney Market Setup "));
109
109
  }
110
110
  log.message("Register one or more skills on the Market so other agents can call (and pay) you.");
111
- // ── Step 1: multiselect categories. Grouped visually: Instant first,
112
- // then Escrow, then Auto. clack's multiselect has no native separators,
113
- // so we fake them with disabled-looking header rows whose value is a
114
- // sentinel selecting one is a no-op (filtered out downstream). ──
115
- const INSTANT_HEADER = "__hdr_instant__";
116
- const ESCROW_HEADER = "__hdr_escrow__";
117
- const AUTO_HEADER = "__hdr_auto__";
118
- const HEADERS = new Set([INSTANT_HEADER, ESCROW_HEADER, AUTO_HEADER]);
119
- const instantRows = CATEGORIES.filter((c) => c.routing === "instant");
120
- const escrowRows = CATEGORIES.filter((c) => c.routing === "escrow");
121
- const autoRows = CATEGORIES.filter((c) => c.routing === "auto");
122
- const groupedOptions = [
123
- { value: INSTANT_HEADER, label: chalk.dim("── Instant · poll for result ──"), hint: "" },
124
- ...instantRows.map((row) => ({ value: row.value, label: ` ${row.value}`, hint: formatHint(row) })),
125
- { value: ESCROW_HEADER, label: chalk.dim("── Escrow · manual approve ──"), hint: "" },
126
- ...escrowRows.map((row) => ({ value: row.value, label: ` ${row.value}`, hint: formatHint(row) })),
127
- { value: AUTO_HEADER, label: chalk.dim("── Auto · routed by price ──"), hint: "" },
128
- ...autoRows.map((row) => ({ value: row.value, label: ` ${row.value}`, hint: formatHint(row) })),
111
+ // ── Step 1: multiselect categories. clack's multiselect has no native
112
+ // separators / disabled rows, so we don't try to draw section headers —
113
+ // any non-selectable row in the option list ends up looking selectable
114
+ // (with predictable user confusion). Instead we just sort so that all
115
+ // instant skills come first, then the single escrow, then the lone
116
+ // "auto" fallback, and embed the routing label directly into each row.
117
+ const orderedAll = [
118
+ ...CATEGORIES.filter((c) => c.routing === "instant"),
119
+ ...CATEGORIES.filter((c) => c.routing === "escrow"),
120
+ ...CATEGORIES.filter((c) => c.routing === "auto"),
129
121
  ];
122
+ // Pad the category name column so the routing tag lines up vertically.
123
+ const nameColumnWidth = Math.max(...orderedAll.map((c) => c.value.length)) + 2;
130
124
  const picked = await multiselect({
131
125
  message: "Pick the skill categories to register (space to toggle, enter to confirm):",
132
- options: groupedOptions,
126
+ options: orderedAll.map((row) => ({
127
+ value: row.value,
128
+ label: `${row.value.padEnd(nameColumnWidth, " ")}${chalk.dim(formatHint(row))}`,
129
+ })),
133
130
  required: true,
134
131
  });
135
132
  if (isCancel(picked)) {
136
133
  cancel("Setup cancelled");
137
134
  process.exit(0);
138
135
  }
139
- // Strip header sentinels — they're visual-only group separators.
140
- const pickedCategories = picked.filter((v) => !HEADERS.has(v));
141
- if (pickedCategories.length === 0) {
142
- cancel("No categories selected");
143
- process.exit(0);
144
- }
136
+ const pickedCategories = picked;
145
137
  // Preserve the canonical CATEGORIES order rather than the click order —
146
138
  // makes the per-skill prompts and the review table read consistently.
147
139
  const orderedRows = CATEGORIES.filter((c) => pickedCategories.includes(c.value));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.17.9",
3
+ "version": "0.17.10",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {