licos-platform-cli 0.3.1__tar.gz → 0.3.3__tar.gz

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.

Potentially problematic release.


This version of licos-platform-cli might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: licos-platform-cli
3
- Version: 0.3.1
3
+ Version: 0.3.3
4
4
  Summary: LICOS platform CLI
5
5
  Requires-Python: >=3.10
6
- Requires-Dist: licos-platform-sdk>=0.4.1
6
+ Requires-Dist: licos-platform-sdk>=0.4.2
@@ -4,11 +4,11 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "licos-platform-cli"
7
- version = "0.3.1"
7
+ version = "0.3.3"
8
8
  description = "LICOS platform CLI"
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
11
- "licos-platform-sdk>=0.4.1",
11
+ "licos-platform-sdk>=0.4.2",
12
12
  ]
13
13
 
14
14
  [project.scripts]
@@ -451,7 +451,7 @@ KNOWLEDGE_HELP = {
451
451
  }
452
452
 
453
453
 
454
- OAUTH_HELP = {
454
+ OAUTH_HELP = {
455
455
  "topic": "oauth",
456
456
  "description": "Manage LICOS OAuth2/OIDC login applications from trusted project runtime code.",
457
457
  "runtime": RUNTIME_ENV,
@@ -495,201 +495,284 @@ OAUTH_HELP = {
495
495
  "grants": {"description": "List application grants.", "parameters": [], "example": "licos-platform oauth grants app-id"},
496
496
  "revoke-grant": {"description": "Revoke one grant.", "parameters": [], "example": "licos-platform oauth revoke-grant grant-id"},
497
497
  },
498
- }
499
-
500
-
501
- UNS_HELP = {
502
- "topic": "uns",
503
- "description": "Project-scoped UNS generation, reconciliation, resource search, and business runtime access.",
504
- "runtime": RUNTIME_ENV,
505
- "rules": [
506
- "Runtime identity selects the project; never pass tenant, workspace, project, external service URL, or token arguments.",
507
- "Query only the blocks and protocols needed for the current document.",
508
- "discover, validate, plan, and finalize are read-only for external systems; apply performs writes.",
509
- "Run apply only after reviewing the current plan, and pass its exact documentHash and planHash with --confirm.",
510
- "UNS.json must not contain platform IDs, external IDs, credentials, MQTT infrastructure IDs, or credential-bearing RTSP URLs.",
498
+ }
499
+
500
+
501
+ UNS_HELP = {
502
+ "topic": "uns",
503
+ "description": "Project-scoped UNS generation, reconciliation, resource search, and business runtime access.",
504
+ "runtime": RUNTIME_ENV,
505
+ "rules": [
506
+ "Runtime identity selects the project; never pass tenant, workspace, project, external service URL, or token arguments.",
507
+ "Query only the blocks and protocols needed for the current document.",
508
+ "discover, validate, plan, and finalize are read-only for external systems; apply performs writes.",
509
+ "Run apply only after reviewing the current plan, and pass its exact documentHash and planHash with --confirm.",
510
+ "UNS.json must not contain platform IDs, external IDs, credentials, MQTT infrastructure IDs, or credential-bearing RTSP URLs.",
511
511
  "Use resource-search before reference bindings; a reference selector must resolve exactly one existing resource.",
512
+ "Point nodes are message-backed. New manifests and changes do not create point storage; existing point storage remains unchanged and does not block point operations.",
513
+ "Use UNSChangeSet for supported isolated structural changes. Remove storage only on an explicit confirmed request. Unsupported operations must fail; do not regenerate a full manifest or call external services directly.",
512
514
  "Use either a current-project node code or --path for business access. Data writes/deletions, point control, and video control require explicit confirmation.",
513
- ],
514
- "sdk": {
515
- "python": "from licos_platform_sdk import uns\nplanned = uns.plan(document)\nresult = uns.apply(document, expected_document_hash=planned['documentHash'], expected_plan_hash=planned['planHash'], confirmed=True)",
516
- },
517
- "commands": {
518
- "schema-current": {
519
- "description": "Get the current complete UNS Schema and block index.",
520
- "parameters": [],
521
- "example": "licos-platform uns schema-current",
522
- },
523
- "schema": {
524
- "description": "Get a complete versioned UNS Schema.",
525
- "parameters": [{"name": "--version", "required": False, "description": "Schema version, default 1.0."}],
526
- "example": "licos-platform uns schema --version 1.0",
527
- },
528
- "schema-blocks": {
529
- "description": "List available blocks for one Schema version.",
530
- "parameters": [{"name": "--version", "required": False, "description": "Schema version, default 1.0."}],
531
- "example": "licos-platform uns schema-blocks",
532
- },
533
- "schema-block": {
534
- "description": "Get one block and optionally its direct dependencies.",
535
- "parameters": [
536
- {"name": "block_code", "required": True, "description": "Block code such as collection-point or uns-node."},
537
- {"name": "--depth", "required": False, "description": "Dependency depth from 0 to 3."},
538
- ],
539
- "example": "licos-platform uns schema-block collection-point --depth 1",
540
- },
541
- "protocol-schema": {
542
- "description": "Get one protocol-specific collection-point Schema and capability status.",
543
- "parameters": [{"name": "protocol", "required": True, "description": "Protocol code such as opcua."}],
544
- "example": "licos-platform uns protocol-schema opcua",
545
- },
546
- "discover": {
547
- "description": "Read a redacted snapshot of reusable industrial resources for the runtime project.",
548
- "parameters": [
549
- {"name": "--resource-type", "required": False, "description": "Resource block to return; can repeat."},
550
- {"name": "--protocol", "required": False, "description": "Protocol capability detail to query; can repeat."},
551
- ],
552
- "example": "licos-platform uns discover --resource-type connections --protocol opcua",
553
- },
554
- "resource-search": {
555
- "description": "Search reusable points, video channels, or other resources and return a manifestSelector without external IDs.",
556
- "parameters": [
557
- {"name": "--resource-type", "required": True, "description": "Resource type such as collectionPoints or videoChannels."},
558
- {"name": "--protocol", "required": False, "description": "Optional protocol filter."},
559
- {"name": "--keyword", "required": False, "description": "Name or business-code search text."},
560
- {"name": "--selector-json", "required": False, "description": "Exact business selector JSON object."},
561
- ],
562
- "example": "licos-platform uns resource-search --resource-type collectionPoints --protocol opcua --keyword TEMP",
563
- },
564
- "bindings": {
565
- "description": "List project UNS node codes, field contracts, and available runtime capabilities.",
566
- "parameters": [],
567
- "example": "licos-platform uns bindings",
568
- },
569
- "path-resolve": {
570
- "description": "Resolve an authorized absolute or relative enterprise UNS path.",
571
- "parameters": [{"name": "path", "required": True, "description": "UNS absolute or relative path."}],
572
- "example": "licos-platform uns path-resolve project:/AREA_01/TEMP_01",
573
- },
574
- "validate": {
575
- "description": "Validate a local JSON document in the runtime project scope.",
576
- "parameters": [{"name": "--file", "required": True, "description": "Local UNS JSON file."}],
577
- "example": "licos-platform uns validate --file UNS.json.candidate",
578
- },
579
- "plan": {
580
- "description": "Create a deterministic read-only reconciliation plan for a local JSON document.",
581
- "parameters": [{"name": "--file", "required": True, "description": "Local UNS JSON file."}],
582
- "example": "licos-platform uns plan --file UNS.json",
583
- },
515
+ ],
516
+ "sdk": {
517
+ "python": "from licos_platform_sdk import uns\nplanned = uns.plan(document)\nresult = uns.apply(document, expected_document_hash=planned['documentHash'], expected_plan_hash=planned['planHash'], confirmed=True)",
518
+ },
519
+ "commands": {
520
+ "schema-current": {
521
+ "description": "Get the current complete UNS Schema and block index.",
522
+ "parameters": [],
523
+ "example": "licos-platform uns schema-current",
524
+ },
525
+ "schema": {
526
+ "description": "Get a complete versioned UNS Schema.",
527
+ "parameters": [{"name": "--version", "required": False, "description": "Schema version, default 1.0."}],
528
+ "example": "licos-platform uns schema --version 1.0",
529
+ },
530
+ "schema-blocks": {
531
+ "description": "List available blocks for one Schema version.",
532
+ "parameters": [{"name": "--version", "required": False, "description": "Schema version, default 1.0."}],
533
+ "example": "licos-platform uns schema-blocks",
534
+ },
535
+ "schema-block": {
536
+ "description": "Get one block and optionally its direct dependencies.",
537
+ "parameters": [
538
+ {"name": "block_code", "required": True, "description": "Block code such as collection-point or uns-node."},
539
+ {"name": "--depth", "required": False, "description": "Dependency depth from 0 to 3."},
540
+ ],
541
+ "example": "licos-platform uns schema-block collection-point --depth 1",
542
+ },
543
+ "protocol-schema": {
544
+ "description": "Get one protocol-specific collection-point Schema and capability status.",
545
+ "parameters": [{"name": "protocol", "required": True, "description": "Protocol code such as opcua."}],
546
+ "example": "licos-platform uns protocol-schema opcua",
547
+ },
548
+ "discover": {
549
+ "description": "Read a redacted snapshot of reusable industrial resources for the runtime project.",
550
+ "parameters": [
551
+ {"name": "--resource-type", "required": False, "description": "Resource block to return; can repeat."},
552
+ {"name": "--protocol", "required": False, "description": "Protocol capability detail to query; can repeat."},
553
+ ],
554
+ "example": "licos-platform uns discover --resource-type connections --protocol opcua",
555
+ },
556
+ "resource-search": {
557
+ "description": "Search reusable points, video channels, or other resources and return a manifestSelector without external IDs.",
558
+ "parameters": [
559
+ {"name": "--resource-type", "required": True, "description": "Resource type such as collectionPoints or videoChannels."},
560
+ {"name": "--protocol", "required": False, "description": "Optional protocol filter."},
561
+ {"name": "--keyword", "required": False, "description": "Name or business-code search text."},
562
+ {"name": "--selector-json", "required": False, "description": "Exact business selector JSON object."},
563
+ ],
564
+ "example": "licos-platform uns resource-search --resource-type collectionPoints --protocol opcua --keyword TEMP",
565
+ },
566
+ "bindings": {
567
+ "description": "List project UNS node codes, field contracts, and available runtime capabilities.",
568
+ "parameters": [],
569
+ "example": "licos-platform uns bindings",
570
+ },
571
+ "path-resolve": {
572
+ "description": "Resolve an authorized absolute or relative enterprise UNS path.",
573
+ "parameters": [{"name": "path", "required": True, "description": "UNS absolute or relative path."}],
574
+ "example": "licos-platform uns path-resolve project:/AREA_01/TEMP_01",
575
+ },
576
+ "validate": {
577
+ "description": "Validate a local JSON document in the runtime project scope.",
578
+ "parameters": [{"name": "--file", "required": True, "description": "Local UNS JSON file."}],
579
+ "example": "licos-platform uns validate --file UNS.json.candidate",
580
+ },
581
+ "plan": {
582
+ "description": "Create a deterministic read-only reconciliation plan for a local JSON document.",
583
+ "parameters": [{"name": "--file", "required": True, "description": "Local UNS JSON file."}],
584
+ "example": "licos-platform uns plan --file UNS.json",
585
+ },
584
586
  "apply": {
585
- "description": "Execute a previously reviewed plan after explicit confirmation and hash verification.",
586
- "parameters": [
587
- {"name": "--file", "required": True, "description": "The exact local UNS JSON document that was planned."},
588
- {"name": "--document-hash", "required": True, "description": "documentHash returned by the reviewed plan."},
589
- {"name": "--plan-hash", "required": True, "description": "planHash returned by the reviewed plan."},
590
- {"name": "--confirm", "required": True, "description": "Explicitly confirm external writes."},
591
- ],
587
+ "description": "Execute a previously reviewed plan after explicit confirmation and hash verification.",
588
+ "parameters": [
589
+ {"name": "--file", "required": True, "description": "The exact local UNS JSON document that was planned."},
590
+ {"name": "--document-hash", "required": True, "description": "documentHash returned by the reviewed plan."},
591
+ {"name": "--plan-hash", "required": True, "description": "planHash returned by the reviewed plan."},
592
+ {"name": "--confirm", "required": True, "description": "Explicitly confirm external writes."},
593
+ ],
592
594
  "example": "licos-platform uns apply --file UNS.json --document-hash <documentHash> --plan-hash <planHash> --confirm",
593
595
  },
594
- "finalize": {
595
- "description": "Validate and atomically install a candidate as project-root UNS.json, revalidate it, and return a read-only plan.",
596
- "parameters": [{"name": "--file", "required": True, "description": "Candidate JSON file inside LICOS_PROJECT_PATH."}],
597
- "example": "licos-platform uns finalize --file .UNS.json.candidate",
596
+ "changes-validate": {
597
+ "description": "Validate one strict UNSChangeSet document without writes.",
598
+ "parameters": [{"name": "--file", "required": True, "description": "Local UNSChangeSet JSON file."}],
599
+ "example": "licos-platform uns changes-validate --file UNS.change.json",
598
600
  },
599
- "data-query": {
600
- "description": "Query stored rows through a data or point UNS node.",
601
- "parameters": [
602
- {"name": "node_code", "required": False, "description": "Current-project UNS node code; mutually exclusive with --path."},
603
- {"name": "--path", "required": False, "description": "Authorized UNS path; mutually exclusive with node_code."},
604
- ],
605
- "example": "licos-platform uns data-query ORDERS --page-size 50",
601
+ "changes-plan": {
602
+ "description": "Resolve targets and create a read-only plan for one UNSChangeSet.",
603
+ "parameters": [{"name": "--file", "required": True, "description": "Local UNSChangeSet JSON file."}],
604
+ "example": "licos-platform uns changes-plan --file UNS.change.json",
606
605
  },
607
- "data-write": {
608
- "description": "Write structured fields through a UNS node after explicit confirmation.",
606
+ "changes-apply": {
607
+ "description": "Apply the exact reviewed UNSChangeSet; destructive or replacement actions require impact confirmation.",
609
608
  "parameters": [
610
- {"name": "node_code", "required": False, "description": "Current-project UNS node code; mutually exclusive with --path."},
611
- {"name": "--path", "required": False, "description": "Authorized UNS path; mutually exclusive with node_code."},
612
- {"name": "--fields-json", "required": True, "description": "Field-value JSON object."},
613
- {"name": "--confirm", "required": True, "description": "Explicitly confirm the write."},
609
+ {"name": "--file", "required": True, "description": "The exact UNSChangeSet document that was planned."},
610
+ {"name": "--document-hash", "required": True, "description": "documentHash returned by changes-plan."},
611
+ {"name": "--plan-hash", "required": True, "description": "planHash returned by changes-plan."},
612
+ {"name": "--confirm", "required": True, "description": "Confirm the planned writes."},
613
+ {"name": "--confirm-impact", "required": False, "description": "Additionally confirm delete, move, replacement, or rebind impact."},
614
614
  ],
615
- "example": "licos-platform uns data-write ORDERS --fields-json '{\"amount\":12}' --confirm",
615
+ "example": "licos-platform uns changes-apply --file UNS.change.json --document-hash <documentHash> --plan-hash <planHash> --confirm --confirm-impact",
616
616
  },
617
- "data-delete": {
618
- "description": "Delete exact rows returned by a prior UNS query after explicit confirmation.",
617
+ "node-update": {
618
+ "description": "Build and plan one supported node metadata update; this command never applies it.",
619
619
  "parameters": [
620
- {"name": "node_code", "required": False, "description": "Current-project UNS node code; mutually exclusive with --path."},
621
- {"name": "--path", "required": False, "description": "Authorized UNS path; mutually exclusive with node_code."},
622
- {"name": "--rows-json", "required": True, "description": "Non-empty JSON array containing exact queried row objects."},
623
- {"name": "--confirm", "required": True, "description": "Explicitly confirm the deletion."},
620
+ {"name": "--path / --node-code", "required": True, "description": "Exactly one project-local target locator."},
621
+ {"name": "--set-json", "required": True, "description": "Supported node fields to replace."},
624
622
  ],
625
- "example": "licos-platform uns data-delete ORDERS --rows-json '[{\"orderNo\":\"SO-1\"}]' --confirm",
623
+ "example": "licos-platform uns node-update --path project:/LINE_1/TEMP_1 --set-json '{\"name\":\"炉温\"}'",
626
624
  },
627
- "point-current": {
628
- "description": "Read the current value of a bound UNS point.",
625
+ "node-move": {
626
+ "description": "Build and plan one project-local node move; this command never applies it.",
629
627
  "parameters": [
630
- {"name": "node_code", "required": False, "description": "Current-project point code; mutually exclusive with --path."},
631
- {"name": "--path", "required": False, "description": "Authorized point path; mutually exclusive with node_code."},
628
+ {"name": "--path / --node-code", "required": True, "description": "Exactly one target locator."},
629
+ {"name": "--parent-path / --parent-node-code", "required": True, "description": "Exactly one destination locator."},
632
630
  ],
633
- "example": "licos-platform uns point-current TEMP_01",
631
+ "example": "licos-platform uns node-move --node-code TEMP_1 --parent-path project:/LINE_2",
634
632
  },
635
- "point-history": {
636
- "description": "Read an ISO-8601 time range of historical point values.",
633
+ "point-rebind": {
634
+ "description": "Build and plan rebinding one point to one exact existing collection point; this command never applies it.",
637
635
  "parameters": [
638
- {"name": "node_code", "required": False, "description": "Current-project point code; mutually exclusive with --path."},
639
- {"name": "--path", "required": False, "description": "Authorized point path; mutually exclusive with node_code."},
640
- {"name": "--start-time / --end-time", "required": True, "description": "UTC ISO-8601 range."},
636
+ {"name": "--path / --node-code", "required": True, "description": "Exactly one point target locator."},
637
+ {"name": "--selector-json", "required": True, "description": "Exact tagCode, taskName, and protocol selector."},
638
+ {"name": "--field-mappings-json", "required": False, "description": "Optional field mapping array."},
641
639
  ],
642
- "example": "licos-platform uns point-history TEMP_01 --start-time 2026-07-13T00:00:00Z --end-time 2026-07-14T00:00:00Z",
640
+ "example": "licos-platform uns point-rebind --node-code TEMP_1 --selector-json '{\"tagCode\":\"T1\",\"taskName\":\"OPC采集\",\"protocol\":\"opcua\"}'",
643
641
  },
644
- "point-write": {
645
- "description": "Dry-run or explicitly confirm a writable point control with audit reason and ticket.",
642
+ "directory-create": {
643
+ "description": "Build and plan creating one project-local grouping directory; this command never applies it.",
646
644
  "parameters": [
647
- {"name": "node_code", "required": False, "description": "Current-project point code; mutually exclusive with --path."},
648
- {"name": "--path", "required": False, "description": "Authorized point path; mutually exclusive with node_code."},
649
- {"name": "--value-json", "required": True, "description": "Typed JSON scalar or value."},
650
- {"name": "--reason / --ticket", "required": True, "description": "Audit context."},
651
- {"name": "--request-id", "required": False, "description": "Idempotency/correlation key; generated by the platform when omitted."},
652
- {"name": "--dry-run / --confirm", "required": True, "description": "Dry-run or explicit execution confirmation."},
645
+ {"name": "--parent-path / --parent-node-code", "required": True, "description": "Exactly one parent locator."},
646
+ {"name": "--node-json", "required": True, "description": "Directory name, stable code, and optional metadata."},
653
647
  ],
654
- "example": "licos-platform uns point-write MOTOR_START --value-json true --reason 'start line' --ticket WO-100 --dry-run",
648
+ "example": "licos-platform uns directory-create --parent-path project:/ --node-json '{\"name\":\"一号产线\",\"code\":\"LINE_1\"}'",
655
649
  },
656
- "video-stream": {
657
- "description": "Get credential-safe playback options for a UNS video node.",
650
+ "connection-update": {
651
+ "description": "生成并规划一个当前项目托管采集连接的增量修改,不直接执行写入。",
658
652
  "parameters": [
659
- {"name": "node_code", "required": False, "description": "Current-project video code; mutually exclusive with --path."},
660
- {"name": "--path", "required": False, "description": "Authorized video path; mutually exclusive with node_code."},
653
+ {"name": "--selector-json", "required": True, "description": "精确的 name、protocol 选择器。"},
654
+ {"name": "--set-json", "required": True, "description": "name、credentialRef 或 configPatch。"},
655
+ {"name": "--output", "required": False, "description": "在项目目录内保存生成的 UNSChangeSet。"},
661
656
  ],
662
- "example": "licos-platform uns video-stream CAMERA_01",
657
+ "example": "licos-platform uns connection-update --selector-json '{\"name\":\"一号PLC\",\"protocol\":\"modbus-tcp\"}' --set-json '{\"configPatch\":{\"host\":\"10.0.0.2\"}}' --output UNS.change.json",
663
658
  },
664
- "video-snapshot": {
665
- "description": "Capture a snapshot from a UNS video node.",
659
+ "collection-task-update": {
660
+ "description": "生成并规划一个当前项目托管采集任务的增量修改,不直接执行写入。",
666
661
  "parameters": [
667
- {"name": "node_code", "required": False, "description": "Current-project video code; mutually exclusive with --path."},
668
- {"name": "--path", "required": False, "description": "Authorized video path; mutually exclusive with node_code."},
662
+ {"name": "--selector-json", "required": True, "description": "精确的 name、protocol、connectionName 选择器。"},
663
+ {"name": "--set-json", "required": True, "description": "name、pollIntervalMs、enabled 或 configPatch。"},
664
+ {"name": "--output", "required": False, "description": "在项目目录内保存生成的 UNSChangeSet。"},
669
665
  ],
670
- "example": "licos-platform uns video-snapshot CAMERA_01",
666
+ "example": "licos-platform uns collection-task-update --selector-json '{\"name\":\"温度采集\",\"protocol\":\"modbus-tcp\",\"connectionName\":\"一号PLC\"}' --set-json '{\"pollIntervalMs\":2000}' --output UNS.change.json",
671
667
  },
672
- "video-control": {
673
- "description": "Execute an explicitly confirmed PTZ or preset action.",
668
+ "point-config-update": {
669
+ "description": "生成并规划一个当前项目托管采集点位配置的增量修改,不改变点位编码和所属任务。",
674
670
  "parameters": [
675
- {"name": "node_code", "required": False, "description": "Current-project video code; mutually exclusive with --path."},
676
- {"name": "--path", "required": False, "description": "Authorized video path; mutually exclusive with node_code."},
677
- {"name": "--action", "required": True, "description": "move, stop, preset-set, or preset-goto."},
678
- {"name": "--parameters-json", "required": False, "description": "Action-specific JSON parameters."},
679
- {"name": "--confirm", "required": True, "description": "Explicitly confirm video control."},
671
+ {"name": "--selector-json", "required": True, "description": "精确的 tagCode、taskName、protocol 选择器。"},
672
+ {"name": "--set-json", "required": True, "description": "点位通用字段或协议 addressPatch。"},
673
+ {"name": "--output", "required": False, "description": "在项目目录内保存生成的 UNSChangeSet。"},
680
674
  ],
681
- "example": "licos-platform uns video-control CAMERA_01 --action move --parameters-json '{\"direction\":\"left\"}' --confirm",
675
+ "example": "licos-platform uns point-config-update --selector-json '{\"tagCode\":\"TEMP_01\",\"taskName\":\"温度采集\",\"protocol\":\"modbus-tcp\"}' --set-json '{\"addressPatch\":{\"address\":\"40002\"}}' --output UNS.change.json",
682
676
  },
683
- },
684
- }
685
-
686
-
687
- HELP_TOPICS = {
677
+ "finalize": {
678
+ "description": "Validate and atomically install a candidate as project-root UNS.json, revalidate it, and return a read-only plan.",
679
+ "parameters": [{"name": "--file", "required": True, "description": "Candidate JSON file inside LICOS_PROJECT_PATH."}],
680
+ "example": "licos-platform uns finalize --file .UNS.json.candidate",
681
+ },
682
+ "data-query": {
683
+ "description": "Query stored rows through a data or point UNS node.",
684
+ "parameters": [
685
+ {"name": "node_code", "required": False, "description": "Current-project UNS node code; mutually exclusive with --path."},
686
+ {"name": "--path", "required": False, "description": "Authorized UNS path; mutually exclusive with node_code."},
687
+ ],
688
+ "example": "licos-platform uns data-query ORDERS --page-size 50",
689
+ },
690
+ "data-write": {
691
+ "description": "Write structured fields through a UNS node after explicit confirmation.",
692
+ "parameters": [
693
+ {"name": "node_code", "required": False, "description": "Current-project UNS node code; mutually exclusive with --path."},
694
+ {"name": "--path", "required": False, "description": "Authorized UNS path; mutually exclusive with node_code."},
695
+ {"name": "--fields-json", "required": True, "description": "Field-value JSON object."},
696
+ {"name": "--confirm", "required": True, "description": "Explicitly confirm the write."},
697
+ ],
698
+ "example": "licos-platform uns data-write ORDERS --fields-json '{\"amount\":12}' --confirm",
699
+ },
700
+ "data-delete": {
701
+ "description": "Delete exact rows returned by a prior UNS query after explicit confirmation.",
702
+ "parameters": [
703
+ {"name": "node_code", "required": False, "description": "Current-project UNS node code; mutually exclusive with --path."},
704
+ {"name": "--path", "required": False, "description": "Authorized UNS path; mutually exclusive with node_code."},
705
+ {"name": "--rows-json", "required": True, "description": "Non-empty JSON array containing exact queried row objects."},
706
+ {"name": "--confirm", "required": True, "description": "Explicitly confirm the deletion."},
707
+ ],
708
+ "example": "licos-platform uns data-delete ORDERS --rows-json '[{\"orderNo\":\"SO-1\"}]' --confirm",
709
+ },
710
+ "point-current": {
711
+ "description": "Read the current value of a bound UNS point.",
712
+ "parameters": [
713
+ {"name": "node_code", "required": False, "description": "Current-project point code; mutually exclusive with --path."},
714
+ {"name": "--path", "required": False, "description": "Authorized point path; mutually exclusive with node_code."},
715
+ ],
716
+ "example": "licos-platform uns point-current TEMP_01",
717
+ },
718
+ "point-history": {
719
+ "description": "Read an ISO-8601 time range of historical point values.",
720
+ "parameters": [
721
+ {"name": "node_code", "required": False, "description": "Current-project point code; mutually exclusive with --path."},
722
+ {"name": "--path", "required": False, "description": "Authorized point path; mutually exclusive with node_code."},
723
+ {"name": "--start-time / --end-time", "required": True, "description": "UTC ISO-8601 range."},
724
+ ],
725
+ "example": "licos-platform uns point-history TEMP_01 --start-time 2026-07-13T00:00:00Z --end-time 2026-07-14T00:00:00Z",
726
+ },
727
+ "point-write": {
728
+ "description": "Dry-run or explicitly confirm a writable point control with audit reason and ticket.",
729
+ "parameters": [
730
+ {"name": "node_code", "required": False, "description": "Current-project point code; mutually exclusive with --path."},
731
+ {"name": "--path", "required": False, "description": "Authorized point path; mutually exclusive with node_code."},
732
+ {"name": "--value-json", "required": True, "description": "Typed JSON scalar or value."},
733
+ {"name": "--reason / --ticket", "required": True, "description": "Audit context."},
734
+ {"name": "--request-id", "required": False, "description": "Idempotency/correlation key; generated by the platform when omitted."},
735
+ {"name": "--dry-run / --confirm", "required": True, "description": "Dry-run or explicit execution confirmation."},
736
+ ],
737
+ "example": "licos-platform uns point-write MOTOR_START --value-json true --reason 'start line' --ticket WO-100 --dry-run",
738
+ },
739
+ "video-stream": {
740
+ "description": "Get credential-safe playback options for a UNS video node.",
741
+ "parameters": [
742
+ {"name": "node_code", "required": False, "description": "Current-project video code; mutually exclusive with --path."},
743
+ {"name": "--path", "required": False, "description": "Authorized video path; mutually exclusive with node_code."},
744
+ ],
745
+ "example": "licos-platform uns video-stream CAMERA_01",
746
+ },
747
+ "video-snapshot": {
748
+ "description": "Capture a snapshot from a UNS video node.",
749
+ "parameters": [
750
+ {"name": "node_code", "required": False, "description": "Current-project video code; mutually exclusive with --path."},
751
+ {"name": "--path", "required": False, "description": "Authorized video path; mutually exclusive with node_code."},
752
+ ],
753
+ "example": "licos-platform uns video-snapshot CAMERA_01",
754
+ },
755
+ "video-control": {
756
+ "description": "Execute an explicitly confirmed PTZ or preset action.",
757
+ "parameters": [
758
+ {"name": "node_code", "required": False, "description": "Current-project video code; mutually exclusive with --path."},
759
+ {"name": "--path", "required": False, "description": "Authorized video path; mutually exclusive with node_code."},
760
+ {"name": "--action", "required": True, "description": "move, stop, preset-set, or preset-goto."},
761
+ {"name": "--parameters-json", "required": False, "description": "Action-specific JSON parameters."},
762
+ {"name": "--confirm", "required": True, "description": "Explicitly confirm video control."},
763
+ ],
764
+ "example": "licos-platform uns video-control CAMERA_01 --action move --parameters-json '{\"direction\":\"left\"}' --confirm",
765
+ },
766
+ },
767
+ }
768
+
769
+
770
+ HELP_TOPICS = {
688
771
  "storage": STORAGE_HELP,
689
772
  "database": DATABASE_HELP,
690
773
  "knowledge": KNOWLEDGE_HELP,
691
- "oauth": OAUTH_HELP,
692
- "uns": UNS_HELP,
774
+ "oauth": OAUTH_HELP,
775
+ "uns": UNS_HELP,
693
776
  }
694
777
 
695
778
 
@@ -701,22 +784,22 @@ def _cmd_help(args: argparse.Namespace) -> dict[str, Any]:
701
784
  if not args.topic:
702
785
  return {
703
786
  "description": "Structured help for LICOS platform CLI topics.",
704
- "usage": [
705
- "licos-platform help storage",
706
- "licos-platform help storage upload-file",
707
- "licos-platform help database",
708
- "licos-platform help database query",
709
- "licos-platform help database export-orm",
710
- "licos-platform help database studio-ensure",
711
- "licos-platform help knowledge",
712
- "licos-platform help knowledge search",
713
- "licos-platform help oauth",
714
- "licos-platform help oauth configure-project",
715
- "licos-platform help uns",
716
- "licos-platform help uns protocol-schema",
717
- ],
718
- "topics": sorted(HELP_TOPICS),
719
- }
787
+ "usage": [
788
+ "licos-platform help storage",
789
+ "licos-platform help storage upload-file",
790
+ "licos-platform help database",
791
+ "licos-platform help database query",
792
+ "licos-platform help database export-orm",
793
+ "licos-platform help database studio-ensure",
794
+ "licos-platform help knowledge",
795
+ "licos-platform help knowledge search",
796
+ "licos-platform help oauth",
797
+ "licos-platform help oauth configure-project",
798
+ "licos-platform help uns",
799
+ "licos-platform help uns protocol-schema",
800
+ ],
801
+ "topics": sorted(HELP_TOPICS),
802
+ }
720
803
  topic = HELP_TOPICS[args.topic]
721
804
  if not args.command:
722
805
  return topic
@@ -11,8 +11,8 @@ from .database_commands import add_database_parser
11
11
  from .help_commands import add_help_parser
12
12
  from .knowledge_commands import add_knowledge_parser
13
13
  from .oauth_commands import add_oauth_parser
14
- from .storage_commands import add_storage_parser
15
- from .uns_commands import add_uns_parser
14
+ from .storage_commands import add_storage_parser
15
+ from .uns_commands import add_uns_parser
16
16
 
17
17
 
18
18
  def _print_json(value: Any) -> None:
@@ -34,8 +34,8 @@ def _build_parser() -> argparse.ArgumentParser:
34
34
  add_storage_parser(subparsers)
35
35
  add_database_parser(subparsers)
36
36
  add_knowledge_parser(subparsers)
37
- add_oauth_parser(subparsers)
38
- add_uns_parser(subparsers)
37
+ add_oauth_parser(subparsers)
38
+ add_uns_parser(subparsers)
39
39
  return parser
40
40
 
41
41