Files
ruvnet--RuView/tools/ruview-cli/src/commands/count.ts
T
rUv 3f462a254d feat(tools): scaffold ruview MCP server + CLI + ADR-104 (#705)
Adds two new npm packages that expose RuView's WiFi-DensePose
sensing capabilities outside the Cognitum appliance ecosystem:

- tools/ruview-mcp/ (@ruv/ruview-mcp) — MCP server with 6 tools:
  ruview_csi_latest, ruview_pose_infer, ruview_count_infer,
  ruview_registry_list, ruview_train_count, ruview_job_status.
  Uses @modelcontextprotocol/sdk with stdio transport.
  6/6 smoke tests pass. TypeScript strict mode, Node 20.

- tools/ruview-cli/ (@ruv/ruview-cli) — Yargs CLI with matching
  subcommands: csi tail, pose infer, count infer, cogs list,
  train count, job status. Same fail-open pattern as the cog
  binaries (WARN to stderr, exit 0 on unavailable sensing-server).

- docs/adr/ADR-104-ruview-mcp-cli-distribution.md — design rationale,
  6-row threat table, packaging plan, acceptance gates, failure modes.

- docs/research/sota-2026-05-22/HORIZON.md — 12-hour horizon plan
  with 7 milestones tracked (M1 complete in this commit).

Both packages are private:true pending the user's publish decision.
Inference is via subprocess to the signed cog binaries (ADR-100/101/103)
— no JS/WASM ML engine bundled.
2026-05-21 23:33:18 -04:00

84 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* ruview count — Person count commands.
*
* count infer — run single-shot person-count inference.
*/
import type { Argv } from "yargs";
import { runCog } from "../cog.js";
import { loadConfig } from "../config.js";
export function countCommand(cli: Argv): void {
cli.command(
"count <action>",
"Person count commands",
(y) =>
y
.positional("action", {
choices: ["infer"] as const,
description: "Action to perform",
})
.option("window", {
type: "string",
description: "Path to a CSI window JSON file (omit to use live sensing-server)",
})
.option("binary", {
type: "string",
description: "Path to cog-person-count binary (default: RUVIEW_COUNT_COG_BINARY)",
})
.option("max-persons", {
type: "number",
default: 7,
description: "Upper bound on person count (17, default: 7)",
}),
async (args) => {
const config = loadConfig();
const binary = (args["binary"] as string | undefined) ?? config.countCogBinary;
if (args.action === "infer") {
const health = await runCog(binary, ["health"]);
if (!health.ok) {
process.stderr.write(
`[WARN] Cog health check failed: ${health.error}\n` +
`Set RUVIEW_COUNT_COG_BINARY or install cog-person-count (ADR-103).\n`
);
process.stdout.write(
JSON.stringify({
ok: false,
warn: true,
error: health.error,
stub: true,
result: {
count: 0,
confidence: 0,
count_p95_low: 0,
count_p95_high: 0,
backend: "stub",
latency_ms: 0,
},
}) + "\n"
);
process.exit(0);
}
process.stdout.write(
JSON.stringify({
ok: true,
stub: true,
note: "M1 stub — real inference wired in M2. Cog health passed.",
result: {
ts: Date.now() / 1000,
count: 0,
confidence: 0,
count_p95_low: 0,
count_p95_high: 0,
backend: "stub",
latency_ms: 0,
},
}) + "\n"
);
}
}
);
}