diff --git a/skills/gmgn-market/SKILL.md b/skills/gmgn-market/SKILL.md index a29c0a8..6bf7718 100644 --- a/skills/gmgn-market/SKILL.md +++ b/skills/gmgn-market/SKILL.md @@ -507,7 +507,7 @@ All filter flags are sent as part of the API request body — the server filters | `--min-progress` / `--max-progress` | float | Bonding curve progress (0–1) | | `--min-marketcap` / `--max-marketcap` | float | Market cap (USD) | | `--min-liquidity` / `--max-liquidity` | float | Liquidity (USD) | -| `--min-created` / `--max-created` | string | Token age (e.g. `1m` / `5m` / `1h` / `24h`) | +| `--min-created` / `--max-created` | duration | Token age — unit suffix recommended: seconds (`30s`, `10s`) or minutes (`0.5m`, `1m`, `5m`, `30m`). Bare numbers (e.g. `5`) are treated as minutes with a warning. | | `--min-holder-count` / `--max-holder-count` | int | Holder count | | `--min-top-holder-rate` / `--max-top-holder-rate` | float | Top-10 holder concentration (0–1) | | `--min-rug-ratio` / `--max-rug-ratio` | float | Rug pull risk score (0–1) | diff --git a/src/commands/market.ts b/src/commands/market.ts index df7d7c5..7cede05 100644 --- a/src/commands/market.ts +++ b/src/commands/market.ts @@ -4,6 +4,22 @@ import { getConfig } from "../config.js"; import { exitOnError, printResult } from "../output.js"; import { validateAddress, validateChain } from "../validate.js"; +// Parse token age string. If a unit suffix is present (s/m), use it as-is. +// Bare numbers (no unit) are treated as minutes with a warning. +function parseDuration(value: string): string { + if (/^\d+(\.\d+)?[sm]$/.test(value)) return value; + if (/^\d+(\.\d+)?$/.test(value)) { + console.warn( + `[gmgn-cli] Warning: no unit specified for duration "${value}" — treating as minutes (${value}m). Use a suffix to be explicit: ${value}s for seconds or ${value}m for minutes.` + ); + return `${value}m`; + } + console.error( + `[gmgn-cli] Invalid duration "${value}". Use seconds (e.g. 30s) or minutes (e.g. 0.5m / 1m / 5m).` + ); + process.exit(1); +} + export function registerMarketCommands(program: Command): void { const market = program.command("market").description("Market data commands"); @@ -76,6 +92,8 @@ export function registerMarketCommands(program: Command): void { trenchesCmd.option(`--${flag} <${def.type}>`, def.desc, parseInt); } else if (def.type === "float") { trenchesCmd.option(`--${flag} <${def.type}>`, def.desc, parseFloat); + } else if (def.type === "duration") { + trenchesCmd.option(`--${flag} `, def.desc, parseDuration); } else { trenchesCmd.option(`--${flag} `, def.desc); } @@ -169,7 +187,7 @@ export function registerMarketCommands(program: Command): void { // ---- Trenches filter field definitions ---- -type TrenchesFieldType = "int" | "float" | "string"; +type TrenchesFieldType = "int" | "float" | "string" | "duration"; interface TrenchesFilterField { api: string; @@ -201,8 +219,8 @@ const TRENCHES_FILTER_FIELDS: TrenchesFilterField[] = [ { api: "min_liquidity", type: "float", desc: "Min liquidity (USD)" }, { api: "max_liquidity", type: "float", desc: "Max liquidity (USD)" }, // Token age - { api: "min_created", type: "string", desc: "Min token age (e.g. 1m / 5m / 30m / 1h / 6h / 24h)" }, - { api: "max_created", type: "string", desc: "Max token age (e.g. 1m / 5m / 30m / 1h / 6h / 24h)" }, + { api: "min_created", type: "duration", desc: "Min token age — unit recommended: seconds (e.g. 30s) or minutes (e.g. 0.5m / 1m / 5m / 30m). Bare numbers treated as minutes." }, + { api: "max_created", type: "duration", desc: "Max token age — unit recommended: seconds (e.g. 30s) or minutes (e.g. 0.5m / 1m / 5m / 30m). Bare numbers treated as minutes." }, // Holders { api: "min_holder_count", type: "int", desc: "Min holder count" }, { api: "max_holder_count", type: "int", desc: "Max holder count" },