mirror of
https://github.com/ruvnet/ruflo.git
synced 2026-11-09 22:13:39 +09:00
feat(iot): ship @claude-flow/plugin-iot-cognitum@1.0.0-alpha.2 with cognitum-iot bin (#1681)
ADR-079 was implemented (239 tests passing across 19 test files) but never shipped as an installable npm package — the marketplace plugin's skills referenced `npx @claude-flow/cli@latest iot ...` which the CLI never exposed. Plugin changes (v3/@claude-flow/plugin-iot-cognitum): - Add src/bin.ts: standalone CLI shim that bootstraps the plugin in-memory, parses argv, resolves multi-word commands (iot fleet add, iot firmware deploy, etc.), aliases short flags, and dispatches to CLICommandDefinition handlers. Defaults `iot register` endpoint to http://169.254.42.1 (the Cognitum Seed link-local USB Ethernet address). - package.json: add `bin: {cognitum-iot: dist/bin.js}`, declare files whitelist, bump to 1.0.0-alpha.2, move @claude-flow/shared to devDependencies (all imports are `import type`, erased at compile) Marketplace plugin changes (plugins/ruflo-iot-cognitum): - Replace 10 files' `npx @claude-flow/cli@latest iot ...` invocations with `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot ...` - iot register endpoint argument now optional with documented default Published @claude-flow/plugin-iot-cognitum@1.0.0-alpha.2 to npm (tags: alpha + latest). Smoke-tested init / list / fleet list / register default-endpoint via npx end-to-end. Co-authored-by: Reuven <cohen@ruv-mac-mini.local>
This commit is contained in:
1 parent
26f3230da2
commit
ec563de2a1
13 files changed
+275
-69
No files matched your search
@@ -37,7 +37,8 @@ claude --plugin-dir plugins/ruflo-iot-cognitum
|
||||
|
||||
```bash
|
||||
# Device lifecycle
|
||||
iot register <endpoint> [--token TOKEN]
|
||||
# `endpoint` defaults to http://169.254.42.1/ (the Seed link-local USB Ethernet address)
|
||||
iot register [endpoint] [--token TOKEN]
|
||||
iot list
|
||||
iot status <device-id>
|
||||
iot pair <device-id>
|
||||
|
||||
@@ -23,15 +23,15 @@ You are a Cognitum Seed device coordinator agent. Your responsibilities:
|
||||
|
||||
### Tools
|
||||
|
||||
- `npx @claude-flow/cli@latest iot register <endpoint>` — register a Seed device
|
||||
- `npx @claude-flow/cli@latest iot status <device-id>` — refresh device state and trust score
|
||||
- `npx @claude-flow/cli@latest iot list` — list all registered devices
|
||||
- `npx @claude-flow/cli@latest iot pair <device-id>` — pair device, promote trust
|
||||
- `npx @claude-flow/cli@latest iot unpair <device-id>` — unpair device, demote trust
|
||||
- `npx @claude-flow/cli@latest iot remove <device-id>` — deregister device
|
||||
- `npx @claude-flow/cli@latest iot mesh <device-id>` — view mesh topology
|
||||
- `npx @claude-flow/cli@latest iot witness <device-id>` — view witness chain
|
||||
- `npx @claude-flow/cli@latest iot witness verify <device-id>` — verify chain integrity
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot register [endpoint]` — register a Seed device (defaults to `http://169.254.42.1/`, the Cognitum Seed link-local USB Ethernet address, when no endpoint is supplied)
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot status <device-id>` — refresh device state and trust score
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot list` — list all registered devices
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot pair <device-id>` — pair device, promote trust
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot unpair <device-id>` — unpair device, demote trust
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot remove <device-id>` — deregister device
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot mesh <device-id>` — view mesh topology
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot witness <device-id>` — view witness chain
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot witness verify <device-id>` — verify chain integrity
|
||||
|
||||
### Anomaly Response
|
||||
|
||||
|
||||
@@ -37,16 +37,16 @@ pending → canary → rolling → complete
|
||||
|
||||
### Tools
|
||||
|
||||
- `npx @claude-flow/cli@latest iot fleet create --name "my-fleet"` — create fleet
|
||||
- `npx @claude-flow/cli@latest iot fleet list` — list all fleets
|
||||
- `npx @claude-flow/cli@latest iot fleet add <fleet-id> <device-id>` — add device
|
||||
- `npx @claude-flow/cli@latest iot fleet remove <fleet-id> <device-id>` — remove device
|
||||
- `npx @claude-flow/cli@latest iot fleet delete <fleet-id>` — delete fleet
|
||||
- `npx @claude-flow/cli@latest iot firmware deploy <fleet-id> --version "2.0.0"` — start rollout
|
||||
- `npx @claude-flow/cli@latest iot firmware advance <rollout-id>` — advance to next stage
|
||||
- `npx @claude-flow/cli@latest iot firmware rollback <rollout-id>` — force rollback
|
||||
- `npx @claude-flow/cli@latest iot firmware status <rollout-id>` — rollout status
|
||||
- `npx @claude-flow/cli@latest iot firmware list` — list all rollouts
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet create --name "my-fleet"` — create fleet
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet list` — list all fleets
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet add <fleet-id> <device-id>` — add device
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet remove <fleet-id> <device-id>` — remove device
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet delete <fleet-id>` — delete fleet
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware deploy <fleet-id> --version "2.0.0"` — start rollout
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware advance <rollout-id>` — advance to next stage
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware rollback <rollout-id>` — force rollback
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware status <rollout-id>` — rollout status
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware list` — list all rollouts
|
||||
|
||||
### Background Workers & Events
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@ You are a telemetry analysis agent for Cognitum Seed devices. Your responsibilit
|
||||
|
||||
### Tools
|
||||
|
||||
- `npx @claude-flow/cli@latest iot anomalies <device-id>` — detect anomalies in recent telemetry
|
||||
- `npx @claude-flow/cli@latest iot baseline <device-id>` — show current baseline
|
||||
- `npx @claude-flow/cli@latest iot baseline <device-id> --compute` — recompute baseline
|
||||
- `npx @claude-flow/cli@latest iot ingest <device-id>` — ingest telemetry vectors
|
||||
- `npx @claude-flow/cli@latest iot query <device-id> --vector "[1,2,3]" --k 10` — k-NN search
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot anomalies <device-id>` — detect anomalies in recent telemetry
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot baseline <device-id>` — show current baseline
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot baseline <device-id> --compute` — recompute baseline
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot ingest <device-id>` — ingest telemetry vectors
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot query <device-id> --vector "[1,2,3]" --k 10` — k-NN search
|
||||
|
||||
### SONA Neural Integration
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ You are a witness chain auditor agent for Cognitum Seed devices. Your responsibi
|
||||
|
||||
### Tools
|
||||
|
||||
- `npx @claude-flow/cli@latest iot witness <device-id>` — view raw witness chain
|
||||
- `npx @claude-flow/cli@latest iot witness verify <device-id>` — verify chain integrity
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot witness <device-id>` — view raw witness chain
|
||||
- `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot witness verify <device-id>` — verify chain integrity
|
||||
|
||||
### Events
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Manage IoT Cognitum Seed devices. Parse subcommand from $ARGUMENTS.
|
||||
Usage: /iot <subcommand> [options]
|
||||
|
||||
Subcommands:
|
||||
- `register <endpoint>` — Register a Seed device by HTTP endpoint
|
||||
- `register [endpoint]` — Register a Seed device by HTTP endpoint (defaults to `http://169.254.42.1/` — the Cognitum Seed link-local address)
|
||||
- `status <device-id>` — Refresh device state and trust score
|
||||
- `list` — List all registered devices
|
||||
- `pair <device-id>` — Pair device, promote trust level
|
||||
@@ -34,26 +34,26 @@ Subcommands:
|
||||
|
||||
Steps by subcommand:
|
||||
|
||||
**register**: `npx @claude-flow/cli@latest iot register ENDPOINT`
|
||||
**status**: `npx @claude-flow/cli@latest iot status DEVICE_ID`
|
||||
**list**: `npx @claude-flow/cli@latest iot list`
|
||||
**pair**: `npx @claude-flow/cli@latest iot pair DEVICE_ID`
|
||||
**unpair**: `npx @claude-flow/cli@latest iot unpair DEVICE_ID`
|
||||
**remove**: `npx @claude-flow/cli@latest iot remove DEVICE_ID`
|
||||
**query**: `npx @claude-flow/cli@latest iot query DEVICE_ID --vector "VECTOR" --k K`
|
||||
**ingest**: `npx @claude-flow/cli@latest iot ingest DEVICE_ID`
|
||||
**mesh**: `npx @claude-flow/cli@latest iot mesh DEVICE_ID`
|
||||
**witness**: `npx @claude-flow/cli@latest iot witness DEVICE_ID`
|
||||
**witness verify**: `npx @claude-flow/cli@latest iot witness verify DEVICE_ID`
|
||||
**fleet create**: `npx @claude-flow/cli@latest iot fleet create --name NAME`
|
||||
**fleet list**: `npx @claude-flow/cli@latest iot fleet list`
|
||||
**fleet add**: `npx @claude-flow/cli@latest iot fleet add FLEET_ID DEVICE_ID`
|
||||
**fleet remove**: `npx @claude-flow/cli@latest iot fleet remove FLEET_ID DEVICE_ID`
|
||||
**fleet delete**: `npx @claude-flow/cli@latest iot fleet delete FLEET_ID`
|
||||
**firmware deploy**: `npx @claude-flow/cli@latest iot firmware deploy FLEET_ID --version VERSION`
|
||||
**firmware advance**: `npx @claude-flow/cli@latest iot firmware advance ROLLOUT_ID`
|
||||
**firmware rollback**: `npx @claude-flow/cli@latest iot firmware rollback ROLLOUT_ID`
|
||||
**firmware status**: `npx @claude-flow/cli@latest iot firmware status ROLLOUT_ID`
|
||||
**firmware list**: `npx @claude-flow/cli@latest iot firmware list`
|
||||
**anomalies**: `npx @claude-flow/cli@latest iot anomalies DEVICE_ID`
|
||||
**baseline**: `npx @claude-flow/cli@latest iot baseline DEVICE_ID --compute`
|
||||
**register**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot register ENDPOINT` (default ENDPOINT=`http://169.254.42.1/` if not supplied — the Cognitum Seed link-local USB Ethernet address)
|
||||
**status**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot status DEVICE_ID`
|
||||
**list**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot list`
|
||||
**pair**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot pair DEVICE_ID`
|
||||
**unpair**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot unpair DEVICE_ID`
|
||||
**remove**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot remove DEVICE_ID`
|
||||
**query**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot query DEVICE_ID --vector "VECTOR" --k K`
|
||||
**ingest**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot ingest DEVICE_ID`
|
||||
**mesh**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot mesh DEVICE_ID`
|
||||
**witness**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot witness DEVICE_ID`
|
||||
**witness verify**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot witness verify DEVICE_ID`
|
||||
**fleet create**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet create --name NAME`
|
||||
**fleet list**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet list`
|
||||
**fleet add**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet add FLEET_ID DEVICE_ID`
|
||||
**fleet remove**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet remove FLEET_ID DEVICE_ID`
|
||||
**fleet delete**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet delete FLEET_ID`
|
||||
**firmware deploy**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware deploy FLEET_ID --version VERSION`
|
||||
**firmware advance**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware advance ROLLOUT_ID`
|
||||
**firmware rollback**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware rollback ROLLOUT_ID`
|
||||
**firmware status**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware status ROLLOUT_ID`
|
||||
**firmware list**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware list`
|
||||
**anomalies**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot anomalies DEVICE_ID`
|
||||
**baseline**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot baseline DEVICE_ID --compute`
|
||||
@@ -7,7 +7,7 @@ argument-hint: "<device-id>"
|
||||
Run Z-score anomaly detection on a device's recent telemetry.
|
||||
|
||||
Steps:
|
||||
1. `npx @claude-flow/cli@latest iot anomalies DEVICE_ID`
|
||||
1. `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot anomalies DEVICE_ID`
|
||||
2. Review detected anomaly types (spike, flatline, drift, oscillation, pattern-break, cluster-outlier)
|
||||
3. If score > 0.9, recommend quarantine
|
||||
4. Store anomaly pattern for learning:
|
||||
|
||||
@@ -6,10 +6,10 @@ argument-hint: "<deploy|advance|rollback|status|list> [options]"
|
||||
---
|
||||
Manage firmware rollouts across device fleets.
|
||||
|
||||
**deploy**: `npx @claude-flow/cli@latest iot firmware deploy FLEET_ID --version VERSION`
|
||||
**advance**: `npx @claude-flow/cli@latest iot firmware advance ROLLOUT_ID`
|
||||
**rollback**: `npx @claude-flow/cli@latest iot firmware rollback ROLLOUT_ID`
|
||||
**status**: `npx @claude-flow/cli@latest iot firmware status ROLLOUT_ID`
|
||||
**list**: `npx @claude-flow/cli@latest iot firmware list`
|
||||
**deploy**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware deploy FLEET_ID --version VERSION`
|
||||
**advance**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware advance ROLLOUT_ID`
|
||||
**rollback**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware rollback ROLLOUT_ID`
|
||||
**status**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware status ROLLOUT_ID`
|
||||
**list**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot firmware list`
|
||||
|
||||
Rollout stages: pending → canary → rolling → complete (or rolled-back)
|
||||
@@ -6,8 +6,8 @@ argument-hint: "<create|list|add|remove|delete> [options]"
|
||||
---
|
||||
Manage device fleets. Parse subcommand from arguments.
|
||||
|
||||
**create**: `npx @claude-flow/cli@latest iot fleet create --name NAME`
|
||||
**list**: `npx @claude-flow/cli@latest iot fleet list`
|
||||
**add**: `npx @claude-flow/cli@latest iot fleet add FLEET_ID DEVICE_ID`
|
||||
**remove**: `npx @claude-flow/cli@latest iot fleet remove FLEET_ID DEVICE_ID`
|
||||
**delete**: `npx @claude-flow/cli@latest iot fleet delete FLEET_ID`
|
||||
**create**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet create --name NAME`
|
||||
**list**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet list`
|
||||
**add**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet add FLEET_ID DEVICE_ID`
|
||||
**remove**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet remove FLEET_ID DEVICE_ID`
|
||||
**delete**: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot fleet delete FLEET_ID`
|
||||
@@ -2,14 +2,17 @@
|
||||
name: iot-register
|
||||
description: Register a Cognitum Seed device by endpoint and establish agent bridge
|
||||
allowed-tools: Bash(npx *) mcp__claude-flow__memory_store Read
|
||||
argument-hint: "<endpoint> [--token PAIRING_TOKEN]"
|
||||
argument-hint: "[endpoint] [--token PAIRING_TOKEN]"
|
||||
---
|
||||
Register a Cognitum Seed device. Creates a SeedClient connection, fetches identity, and assigns initial trust level.
|
||||
|
||||
Default endpoint: `http://169.254.42.1/` — the Cognitum Seed link-local USB Ethernet address. Use this when no endpoint is supplied.
|
||||
|
||||
Steps:
|
||||
1. `npx @claude-flow/cli@latest iot register ENDPOINT`
|
||||
2. If pairing token provided: `npx @claude-flow/cli@latest iot pair DEVICE_ID`
|
||||
3. Show device status: `npx @claude-flow/cli@latest iot status DEVICE_ID`
|
||||
1. Resolve ENDPOINT: use the user-supplied value, or default to `http://169.254.42.1/`.
|
||||
2. `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot register ENDPOINT`
|
||||
3. If pairing token provided: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot pair DEVICE_ID`
|
||||
4. Show device status: `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot status DEVICE_ID`
|
||||
|
||||
Store registration event:
|
||||
`mcp__claude-flow__memory_store({ key: "iot-register-DEVICEID", value: "Registered at ENDPOINT", namespace: "iot-devices" })`
|
||||
@@ -7,7 +7,7 @@ argument-hint: "<device-id>"
|
||||
Verify the witness chain integrity for a Cognitum Seed device.
|
||||
|
||||
Steps:
|
||||
1. `npx @claude-flow/cli@latest iot witness verify DEVICE_ID`
|
||||
1. `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot witness verify DEVICE_ID`
|
||||
2. Check for epoch gaps and hash chain breaks
|
||||
3. Report integrity score (0.0–1.0)
|
||||
4. If gaps found, store for audit trail:
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
{
|
||||
"name": "@claude-flow/plugin-iot-cognitum",
|
||||
"version": "1.0.0-alpha.1",
|
||||
"version": "1.0.0-alpha.2",
|
||||
"description": "IoT Cognitum Seed device-agent bridge — treat every Seed as a Ruflo agent",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"bin": {
|
||||
"cognitum-iot": "dist/bin.js"
|
||||
},
|
||||
"files": [
|
||||
"dist/**",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "vitest run",
|
||||
@@ -13,10 +21,10 @@
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@claude-flow/shared": "workspace:*",
|
||||
"@cognitum-one/sdk": "^0.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@claude-flow/shared": "workspace:*",
|
||||
"typescript": "^5.4.0",
|
||||
"vitest": "^1.6.0"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Standalone CLI shim for @claude-flow/plugin-iot-cognitum.
|
||||
* Maps `cognitum-iot <subcommand> [args]` -> CLICommandDefinition handlers.
|
||||
*
|
||||
* Endpoint default: when --endpoint/-e is omitted on `register`,
|
||||
* defaults to http://169.254.42.1 (the Cognitum Seed link-local USB address).
|
||||
*/
|
||||
|
||||
import { IoTCognitumPlugin } from './plugin.js';
|
||||
import type { PluginContext } from '@claude-flow/shared/src/plugin-interface.js';
|
||||
|
||||
const SEED_DEFAULT_ENDPOINT = 'http://169.254.42.1';
|
||||
|
||||
function makeContext(): PluginContext {
|
||||
// Minimal in-memory context for standalone CLI use.
|
||||
const noop = () => undefined;
|
||||
return {
|
||||
config: {
|
||||
fleetId: process.env.IOT_FLEET_ID ?? 'default',
|
||||
zoneId: process.env.IOT_ZONE_ID ?? 'zone-0',
|
||||
tlsInsecure: process.env.IOT_TLS_INSECURE !== 'false',
|
||||
},
|
||||
eventBus: {
|
||||
emit: noop,
|
||||
on: noop,
|
||||
off: noop,
|
||||
once: noop,
|
||||
} as unknown as PluginContext['eventBus'],
|
||||
logger: {
|
||||
info: (...a: unknown[]) => console.log('[info]', ...a),
|
||||
warn: (...a: unknown[]) => console.warn('[warn]', ...a),
|
||||
error: (...a: unknown[]) => console.error('[error]', ...a),
|
||||
debug: (...a: unknown[]) => process.env.DEBUG && console.error('[debug]', ...a),
|
||||
} as unknown as PluginContext['logger'],
|
||||
services: {
|
||||
get: () => undefined,
|
||||
register: noop,
|
||||
has: () => false,
|
||||
} as unknown as PluginContext['services'],
|
||||
};
|
||||
}
|
||||
|
||||
interface ParsedArgs {
|
||||
_: string[];
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse argv minimally: positional -> _, --flag value, --flag=value, --boolean,
|
||||
* short -e value. Numeric values stay as strings (handlers coerce as needed).
|
||||
*/
|
||||
function parseArgs(argv: string[]): ParsedArgs {
|
||||
const out: ParsedArgs = { _: [] };
|
||||
for (let i = 0; i < argv.length; i++) {
|
||||
const a = argv[i]!;
|
||||
if (a.startsWith('--')) {
|
||||
const eq = a.indexOf('=');
|
||||
if (eq > -1) {
|
||||
out[a.slice(2, eq)] = a.slice(eq + 1);
|
||||
} else {
|
||||
const key = a.slice(2);
|
||||
const next = argv[i + 1];
|
||||
if (next === undefined || next.startsWith('-')) {
|
||||
out[key] = true;
|
||||
} else {
|
||||
out[key] = next;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else if (a.startsWith('-') && a.length > 1) {
|
||||
const key = a.slice(1);
|
||||
const next = argv[i + 1];
|
||||
if (next === undefined || next.startsWith('-')) {
|
||||
out[key] = true;
|
||||
} else {
|
||||
out[key] = next;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
out._.push(a);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function aliasShortToLong(args: ParsedArgs): ParsedArgs {
|
||||
// Most common short flags used across the iot commands.
|
||||
const aliases: Record<string, string> = {
|
||||
e: 'endpoint',
|
||||
f: 'fleet-id',
|
||||
z: 'zone-id',
|
||||
d: 'device-id',
|
||||
v: 'version',
|
||||
k: 'k',
|
||||
n: 'name',
|
||||
t: 'token',
|
||||
};
|
||||
for (const [s, l] of Object.entries(aliases)) {
|
||||
if (s in args && !(l in args)) {
|
||||
args[l] = args[s];
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a subcommand path against command definitions.
|
||||
* Supports multi-word commands: `iot fleet add`, `iot firmware deploy`, etc.
|
||||
* Tries longest match first.
|
||||
*/
|
||||
function resolveCommand(
|
||||
argv: string[],
|
||||
commandNames: string[],
|
||||
): { name: string; rest: string[] } | null {
|
||||
// Strip the leading "iot" prefix from each defined command for matching.
|
||||
const tokens = argv.slice();
|
||||
// Try longest match (3 tokens, then 2, then 1).
|
||||
for (const len of [3, 2, 1]) {
|
||||
if (tokens.length < len) continue;
|
||||
const probe = 'iot ' + tokens.slice(0, len).join(' ');
|
||||
if (commandNames.includes(probe)) {
|
||||
return { name: probe, rest: tokens.slice(len) };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function printHelp(commandNames: string[]): void {
|
||||
console.log('cognitum-iot — Cognitum Seed device-agent CLI');
|
||||
console.log('');
|
||||
console.log('Usage: cognitum-iot <subcommand> [options]');
|
||||
console.log('');
|
||||
console.log('Default endpoint: ' + SEED_DEFAULT_ENDPOINT + ' (Seed link-local USB address)');
|
||||
console.log('');
|
||||
console.log('Subcommands:');
|
||||
for (const n of commandNames) {
|
||||
console.log(' ' + n.replace(/^iot /, ''));
|
||||
}
|
||||
console.log('');
|
||||
console.log('Run "cognitum-iot <subcommand> --help" for command-specific options.');
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const argv = process.argv.slice(2);
|
||||
|
||||
if (argv.length === 0 || argv[0] === '--help' || argv[0] === '-h') {
|
||||
// Need to bootstrap to enumerate commands.
|
||||
}
|
||||
|
||||
const plugin = new IoTCognitumPlugin();
|
||||
const context = makeContext();
|
||||
await plugin.initialize(context);
|
||||
|
||||
const commands = plugin.registerCLICommands();
|
||||
const commandNames = commands.map((c) => c.name);
|
||||
|
||||
if (argv.length === 0 || argv[0] === '--help' || argv[0] === '-h') {
|
||||
printHelp(commandNames);
|
||||
return;
|
||||
}
|
||||
|
||||
const resolved = resolveCommand(argv, commandNames);
|
||||
if (!resolved) {
|
||||
console.error('Unknown subcommand: ' + argv.join(' '));
|
||||
console.error('Run "cognitum-iot --help" to list available subcommands.');
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const cmd = commands.find((c) => c.name === resolved.name)!;
|
||||
const args = aliasShortToLong(parseArgs(resolved.rest));
|
||||
|
||||
// Endpoint default for `iot register`: fall back to Seed link-local address.
|
||||
if (resolved.name === 'iot register' && !args['endpoint']) {
|
||||
args['endpoint'] = SEED_DEFAULT_ENDPOINT;
|
||||
console.error(`[info] No --endpoint supplied; defaulting to ${SEED_DEFAULT_ENDPOINT}`);
|
||||
}
|
||||
|
||||
try {
|
||||
await cmd.handler(args as never);
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
console.error('Error: ' + msg);
|
||||
process.exitCode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(process.exitCode ?? 0))
|
||||
.catch((err) => {
|
||||
console.error('Fatal: ' + (err instanceof Error ? err.message : String(err)));
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in new issue
Block a user