ceddcozum 0.1.5 → 0.1.7
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.
- package/dist/index.js +117 -38
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -27086,11 +27086,34 @@ var toolsMetadata = [
|
|
|
27086
27086
|
}
|
|
27087
27087
|
];
|
|
27088
27088
|
|
|
27089
|
+
// ../src/lib/hiddenToolIds.ts
|
|
27090
|
+
var HIDDEN_TOOL_IDS = [
|
|
27091
|
+
"steroid-tapering",
|
|
27092
|
+
"periop-adrenal",
|
|
27093
|
+
"preop-diabetes",
|
|
27094
|
+
"dka-fluid",
|
|
27095
|
+
"gri",
|
|
27096
|
+
"basal-bolus",
|
|
27097
|
+
"meal-bolus",
|
|
27098
|
+
"custom-iv-fluid",
|
|
27099
|
+
"cp-height",
|
|
27100
|
+
"oral-phosphorus",
|
|
27101
|
+
"corrected-calcium",
|
|
27102
|
+
"gfr",
|
|
27103
|
+
"leptin-sds"
|
|
27104
|
+
];
|
|
27105
|
+
|
|
27089
27106
|
// src/formatter.ts
|
|
27090
|
-
var
|
|
27091
|
-
var
|
|
27092
|
-
var
|
|
27093
|
-
var
|
|
27107
|
+
var useColor = !process.env.NO_COLOR && !!process.stdout.isTTY;
|
|
27108
|
+
var bold = (s) => useColor ? `\x1B[1m${s}\x1B[0m` : s;
|
|
27109
|
+
var dim = (s) => useColor ? `\x1B[2m${s}\x1B[0m` : s;
|
|
27110
|
+
var yellow = (s) => useColor ? `\x1B[33m${s}\x1B[0m` : s;
|
|
27111
|
+
var cyan = (s) => useColor ? `\x1B[36m${s}\x1B[0m` : s;
|
|
27112
|
+
function formatPercentile2(p) {
|
|
27113
|
+
if (p <= 0.02) return "<P0.02";
|
|
27114
|
+
if (p >= 99.98) return ">P99.98";
|
|
27115
|
+
return `P${p.toFixed(1)}`;
|
|
27116
|
+
}
|
|
27094
27117
|
function formatHuman(toolName, results, schema) {
|
|
27095
27118
|
const lines = [];
|
|
27096
27119
|
lines.push("");
|
|
@@ -27101,12 +27124,13 @@ function formatHuman(toolName, results, schema) {
|
|
|
27101
27124
|
const warnings = results.filter((r) => r.tag === "warning" || r.tag === "validation");
|
|
27102
27125
|
const info = results.filter((r) => r.tag === "info" || r.tag === "note");
|
|
27103
27126
|
const altRows = results.filter((r) => r.tag === "alt" || r.tag === "sexAlt");
|
|
27127
|
+
const padWidth = Math.max(20, ...dataRows.map((r) => r.label.length)) + 2;
|
|
27104
27128
|
for (const r of dataRows) {
|
|
27105
|
-
const label = r.label.padEnd(
|
|
27129
|
+
const label = r.label.padEnd(padWidth);
|
|
27106
27130
|
const value = r.value;
|
|
27107
27131
|
const unit = r.unit ? dim(` ${r.unit}`) : "";
|
|
27108
27132
|
const sds = r.sds != null ? cyan(` SDS: ${r.sds >= 0 ? "+" : ""}${r.sds.toFixed(2)}`) : "";
|
|
27109
|
-
const pct = r.percentile != null ? dim(` (
|
|
27133
|
+
const pct = r.percentile != null ? dim(` (${formatPercentile2(r.percentile)})`) : "";
|
|
27110
27134
|
let sdsNote = "";
|
|
27111
27135
|
if (r.sdsReason === "outOfRange") {
|
|
27112
27136
|
sdsNote = yellow(" (age out of reference range)");
|
|
@@ -27131,8 +27155,9 @@ function formatHuman(toolName, results, schema) {
|
|
|
27131
27155
|
lines.push("");
|
|
27132
27156
|
for (const r of altRows) {
|
|
27133
27157
|
if (r.altToolName && r.altArgs) {
|
|
27158
|
+
const kvParts = Object.entries(r.altArgs).map(([k, v]) => `${k}=${v}`).join(" ");
|
|
27134
27159
|
lines.push(` ${dim("tip:")} ${r.value}`);
|
|
27135
|
-
lines.push(` ${dim(" ceddcozum")} ${r.altToolName} ${
|
|
27160
|
+
lines.push(` ${dim(" ceddcozum")} ${r.altToolName} ${kvParts}`);
|
|
27136
27161
|
} else {
|
|
27137
27162
|
lines.push(` ${dim("tip:")} ${r.value}`);
|
|
27138
27163
|
}
|
|
@@ -27147,28 +27172,14 @@ function formatHuman(toolName, results, schema) {
|
|
|
27147
27172
|
const noop = () => null;
|
|
27148
27173
|
globalThis.localStorage = { getItem: noop, setItem: noop, removeItem: noop, clear: noop, length: 0, key: noop };
|
|
27149
27174
|
})();
|
|
27150
|
-
var
|
|
27151
|
-
var
|
|
27152
|
-
var
|
|
27153
|
-
var
|
|
27154
|
-
var
|
|
27155
|
-
var
|
|
27156
|
-
var
|
|
27157
|
-
|
|
27158
|
-
"periop-adrenal",
|
|
27159
|
-
"preop-diabetes",
|
|
27160
|
-
"dka-fluid",
|
|
27161
|
-
"gri",
|
|
27162
|
-
"basal-bolus",
|
|
27163
|
-
"meal-bolus",
|
|
27164
|
-
"custom-iv-fluid",
|
|
27165
|
-
"cp-height",
|
|
27166
|
-
"oral-phosphorus",
|
|
27167
|
-
"corrected-calcium",
|
|
27168
|
-
"gfr",
|
|
27169
|
-
"leptin-sds"
|
|
27170
|
-
];
|
|
27171
|
-
var VERSION = "0.1.5";
|
|
27175
|
+
var useColor2 = !process.env.NO_COLOR && !!process.stdout.isTTY;
|
|
27176
|
+
var bold2 = (s) => useColor2 ? `\x1B[1m${s}\x1B[0m` : s;
|
|
27177
|
+
var dim2 = (s) => useColor2 ? `\x1B[2m${s}\x1B[0m` : s;
|
|
27178
|
+
var cyan2 = (s) => useColor2 ? `\x1B[36m${s}\x1B[0m` : s;
|
|
27179
|
+
var green = (s) => useColor2 ? `\x1B[32m${s}\x1B[0m` : s;
|
|
27180
|
+
var yellow2 = (s) => useColor2 ? `\x1B[33m${s}\x1B[0m` : s;
|
|
27181
|
+
var magenta = (s) => useColor2 ? `\x1B[35m${s}\x1B[0m` : s;
|
|
27182
|
+
var VERSION = true ? "0.1.7" : "0.0.0-dev";
|
|
27172
27183
|
var visibleSchemas = toolSchemas.filter(
|
|
27173
27184
|
(s) => !HIDDEN_TOOL_IDS.includes(s.function.name)
|
|
27174
27185
|
);
|
|
@@ -27205,6 +27216,56 @@ var CATEGORY_LABELS = {
|
|
|
27205
27216
|
function getSchemaByName(name) {
|
|
27206
27217
|
return visibleSchemas.find((s) => s.function.name === name);
|
|
27207
27218
|
}
|
|
27219
|
+
function camelToKebab(s) {
|
|
27220
|
+
return s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
27221
|
+
}
|
|
27222
|
+
function kebabToCamel(s) {
|
|
27223
|
+
return s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
27224
|
+
}
|
|
27225
|
+
function levenshtein(a, b) {
|
|
27226
|
+
const m = a.length, n = b.length;
|
|
27227
|
+
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
27228
|
+
for (let i = 0; i <= m; i++) dp[i][0] = i;
|
|
27229
|
+
for (let j = 0; j <= n; j++) dp[0][j] = j;
|
|
27230
|
+
for (let i = 1; i <= m; i++) {
|
|
27231
|
+
for (let j = 1; j <= n; j++) {
|
|
27232
|
+
dp[i][j] = Math.min(
|
|
27233
|
+
dp[i - 1][j] + 1,
|
|
27234
|
+
dp[i][j - 1] + 1,
|
|
27235
|
+
dp[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)
|
|
27236
|
+
);
|
|
27237
|
+
}
|
|
27238
|
+
}
|
|
27239
|
+
return dp[m][n];
|
|
27240
|
+
}
|
|
27241
|
+
function suggestTool(input) {
|
|
27242
|
+
let best = null;
|
|
27243
|
+
let bestDist = 4;
|
|
27244
|
+
for (const s of visibleSchemas) {
|
|
27245
|
+
const d = levenshtein(input.toLowerCase(), s.function.name.toLowerCase());
|
|
27246
|
+
if (d < bestDist) {
|
|
27247
|
+
bestDist = d;
|
|
27248
|
+
best = s.function.name;
|
|
27249
|
+
}
|
|
27250
|
+
}
|
|
27251
|
+
return best;
|
|
27252
|
+
}
|
|
27253
|
+
function exampleValue(key, prop) {
|
|
27254
|
+
if (prop.enum) return prop.enum[0];
|
|
27255
|
+
if (prop.type === "boolean") return "true";
|
|
27256
|
+
const k = key.toLowerCase();
|
|
27257
|
+
if (k === "age" || k.includes("age")) return "5.5";
|
|
27258
|
+
if (k === "height") return "110";
|
|
27259
|
+
if (k === "weight") return "19";
|
|
27260
|
+
if (k.includes("circumference") || k === "headcircumference") return "50";
|
|
27261
|
+
if (k === "gestationalweeks" || k.includes("gestational")) return "38";
|
|
27262
|
+
if (k === "birthweight") return "3200";
|
|
27263
|
+
if (k.includes("percent")) return "7.5";
|
|
27264
|
+
if (k.includes("systolic")) return "110";
|
|
27265
|
+
if (k.includes("diastolic")) return "70";
|
|
27266
|
+
if (prop.type === "number") return "10";
|
|
27267
|
+
return "value";
|
|
27268
|
+
}
|
|
27208
27269
|
function printHelp() {
|
|
27209
27270
|
console.log(`
|
|
27210
27271
|
${bold2("ceddcozum")} v${VERSION} ${dim2("\u2014 Pediatric clinical calculators")}
|
|
@@ -27236,7 +27297,8 @@ function printList() {
|
|
|
27236
27297
|
const name = schema.function.name;
|
|
27237
27298
|
const meta = findMeta(name);
|
|
27238
27299
|
const category = getCategoryForSchema(name);
|
|
27239
|
-
const
|
|
27300
|
+
const raw = meta?.subtitleFallback ?? schema.function.description;
|
|
27301
|
+
const subtitle = raw.length > 50 ? raw.slice(0, 49) + "\u2026" : raw;
|
|
27240
27302
|
if (!byCategory.has(category)) byCategory.set(category, []);
|
|
27241
27303
|
byCategory.get(category).push({ id: name, subtitle });
|
|
27242
27304
|
}
|
|
@@ -27273,7 +27335,7 @@ ${cyan2(String(visibleSchemas.length))} tools available:
|
|
|
27273
27335
|
console.log();
|
|
27274
27336
|
}
|
|
27275
27337
|
function extractUnit(description) {
|
|
27276
|
-
const match = description.match(/\bin\s+(
|
|
27338
|
+
const match = description.match(/\bin\s+([\w/°µ²%]+(?:\s+per\s+\w+)?)\s*[.;,)]*$/i);
|
|
27277
27339
|
if (match) return match[1];
|
|
27278
27340
|
const parenMatch = description.match(/\((\w+\/\w+)\)\s*$/);
|
|
27279
27341
|
if (parenMatch) return parenMatch[1];
|
|
@@ -27307,9 +27369,7 @@ ${bold2("EXAMPLE")}`);
|
|
|
27307
27369
|
const exParts = [];
|
|
27308
27370
|
for (const key of required) {
|
|
27309
27371
|
const prop = params.properties[key];
|
|
27310
|
-
|
|
27311
|
-
else if (prop?.type === "number") exParts.push(`${key}=...`);
|
|
27312
|
-
else exParts.push(`${key}=...`);
|
|
27372
|
+
exParts.push(`${key}=${exampleValue(key, prop ?? { type: "string" })}`);
|
|
27313
27373
|
}
|
|
27314
27374
|
console.log(` ${dim2("$")} ceddcozum ${name} ${exParts.join(" ")}`);
|
|
27315
27375
|
console.log();
|
|
@@ -27363,7 +27423,9 @@ function parseKeyValueArgs(pairs, schema) {
|
|
|
27363
27423
|
}
|
|
27364
27424
|
const rawKey = pair.slice(0, eqIdx);
|
|
27365
27425
|
const raw = pair.slice(eqIdx + 1);
|
|
27366
|
-
const key = Object.keys(props).find(
|
|
27426
|
+
const key = Object.keys(props).find(
|
|
27427
|
+
(k) => k.toLowerCase() === rawKey.toLowerCase() || camelToKebab(k) === rawKey.toLowerCase() || k.toLowerCase() === kebabToCamel(rawKey).toLowerCase()
|
|
27428
|
+
) ?? rawKey;
|
|
27367
27429
|
const prop = props[key];
|
|
27368
27430
|
if (prop?.type === "number") {
|
|
27369
27431
|
const n = Number(raw);
|
|
@@ -27405,7 +27467,8 @@ ${yellow2("!")} Validation errors for ${bold2(name)}:`);
|
|
|
27405
27467
|
process.exit(1);
|
|
27406
27468
|
}
|
|
27407
27469
|
if (format === "json") {
|
|
27408
|
-
|
|
27470
|
+
const dataResults = results.filter((r) => r.tag !== "alt" && r.tag !== "sexAlt");
|
|
27471
|
+
console.log(JSON.stringify(dataResults, null, 2));
|
|
27409
27472
|
} else {
|
|
27410
27473
|
console.log(formatHuman(name, results, schema));
|
|
27411
27474
|
}
|
|
@@ -27423,7 +27486,7 @@ function main() {
|
|
|
27423
27486
|
format: { type: "string", short: "f", default: "human" }
|
|
27424
27487
|
}
|
|
27425
27488
|
});
|
|
27426
|
-
if (values.help) {
|
|
27489
|
+
if (values.help && positionals.length === 0) {
|
|
27427
27490
|
printHelp();
|
|
27428
27491
|
return;
|
|
27429
27492
|
}
|
|
@@ -27456,10 +27519,26 @@ function main() {
|
|
|
27456
27519
|
const schema = getSchemaByName(toolName);
|
|
27457
27520
|
if (!schema) {
|
|
27458
27521
|
console.error(`${yellow2("!")} Unknown tool: ${bold2(toolName)}`);
|
|
27459
|
-
|
|
27522
|
+
const suggestion = suggestTool(toolName);
|
|
27523
|
+
if (suggestion) {
|
|
27524
|
+
console.error(` Did you mean ${cyan2(suggestion)}?`);
|
|
27525
|
+
} else {
|
|
27526
|
+
console.error(` Run ${cyan2("'ceddcozum --list'")} to see available tools.`);
|
|
27527
|
+
}
|
|
27460
27528
|
process.exit(1);
|
|
27461
27529
|
}
|
|
27530
|
+
if (values.help) {
|
|
27531
|
+
printToolInfo(toolName);
|
|
27532
|
+
return;
|
|
27533
|
+
}
|
|
27462
27534
|
const kvPairs = positionals.slice(1).filter((p) => p.includes("="));
|
|
27535
|
+
const nonKvArgs = positionals.slice(1).filter((p) => !p.includes("="));
|
|
27536
|
+
if (nonKvArgs.length > 0 && !values.args) {
|
|
27537
|
+
console.error(`${yellow2("!")} Unexpected arguments: ${bold2(nonKvArgs.join(" "))}`);
|
|
27538
|
+
console.error(` Use ${cyan2("key=value")} format: ${dim2(`ceddcozum ${toolName} sex=male age=5.5`)}`);
|
|
27539
|
+
console.error(` Run ${cyan2(`'ceddcozum ${toolName}'`)} to see parameter names.`);
|
|
27540
|
+
process.exit(1);
|
|
27541
|
+
}
|
|
27463
27542
|
if (values.args) {
|
|
27464
27543
|
let args;
|
|
27465
27544
|
try {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ceddcozum",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "CEDD Cozum pediatric clinical calculators - CLI interface",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bora Ulukapı",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/
|
|
9
|
+
"url": "https://github.com/borean/ceddcozum"
|
|
10
10
|
},
|
|
11
11
|
"keywords": [
|
|
12
12
|
"pediatrics",
|