feat: add unidesk hwpod operations skill
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
---
|
||||
name: unidesk-hwpod-ops
|
||||
description: UniDesk HWLAB HWPOD 节点运维技能,覆盖 Windows 单文件 Python UI `hwlab-node.py` 的发现、安装、GUI/托盘、连接、更新、日志、诊断、nodeId、workspace、HWPOD node-ops、MDTODO source 和 legacy Bun runner 漂移。用户提到 hwpod-node、hwlab-node、Python UI node、HWPOD 节点上下线、D601/G14-WSL 硬件节点、workspace 绑定或 HWLAB Web MDTODO 读取时使用。
|
||||
---
|
||||
|
||||
# UniDesk HWPOD Ops
|
||||
|
||||
以当前 HWLAB v0.3 Python UI node 为默认运维对象。旧 `$hwpod-ops` 中的 TypeScript/Bun `serve|connect` 只用于历史漂移调查,不作为新节点完成态。
|
||||
|
||||
## P0 Boundaries
|
||||
|
||||
- 当前 HWLAB 固定运行面由 UniDesk `config/hwlab-node-lanes.yaml` 选择;先运行 `cicd status` 和 `source-workspace status`,不要复用旧 G14/v0.2 URL。
|
||||
- Python UI node 权威源码是选中 HWLAB source workspace 的 `tools/hwlab-node.py`;发布版本和 SHA 由选中 origin 的 `/v1/hwlab-node/update` 与 `/v1/hwlab-node/download/hwlab-node.py` 给出。
|
||||
- 节点、workspace、HWPOD resource、MDTODO source、endpoint 和 Secret 都必须进入 owning YAML/configRef。`~/.hwlab/config.json` 是桌面应用配置,不是平台资源真相。
|
||||
- Secret 只通过 YAML `sourceRef`/`targetKey` 和受控入口下发。状态、日志和 issue 只披露 presence、fingerprint 和脱敏摘要。
|
||||
- Windows 节点使用主动出站 WebSocket;不要为用户 PC 增加入站端口或 direct-url fallback。
|
||||
- Windows Python UI node 必须优先用目标 Windows 交互用户可见的原生 `python.exe` 启动。不要用 WSL Python、SSH helper 自带解释器、Bun runner 或非交互 Windows service 替代;解释器路径/版本必须进入 node profile 与状态证据。
|
||||
- 调查可只读访问现场。安装、注册、更新、停止旧 runner 或改 MDTODO source 属于运行面变更,必须先加载 `$dad-dev`;部署/rollout 同时加载 `$unidesk-cicd`,YAML 变更同时加载 `$unidesk-ymalops`。
|
||||
- 远端操作走 `$unidesk-trans`。普通 `trans` 保持短连接;GUI 进程不得作为透传子进程长挂。
|
||||
- Python node 当前若没有 workspace allowlist/规范化、注册认证或 capability parity,不得把“WebSocket 已连接”报告为 HWPOD/MDTODO 可用。
|
||||
|
||||
## Read-Only Triage
|
||||
|
||||
```bash
|
||||
bun scripts/cli.ts cicd status --node NC01
|
||||
bun scripts/cli.ts hwlab nodes control-plane source-workspace status --node NC01 --lane v03
|
||||
|
||||
trans <provider>:win ps '[ordered]@{home=$HOME; python=(python --version 2>&1 | Out-String).Trim(); config=(Test-Path (Join-Path $HOME ".hwlab\\config.json")); log=(Test-Path (Join-Path $HOME ".hwlab\\logs\\hwlab-node.log"))} | ConvertTo-Json -Compress'
|
||||
trans <provider>:win ps 'Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match "hwlab-node|hwpod-node" } | Select-Object ProcessId,Name,CommandLine | ConvertTo-Json -Compress'
|
||||
trans <provider>:win ps 'Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object { $_.TaskName -match "HWLAB|HWPOD" } | Select-Object TaskName,State | ConvertTo-Json -Compress'
|
||||
```
|
||||
|
||||
Classify results separately:
|
||||
|
||||
- `desktop-ready`: Python/tkinter and an interactive Windows session are available.
|
||||
- `process-ready`: exactly one intended Python UI process is alive; no conflicting Bun authority.
|
||||
- `registered`: cloud registry acknowledges the expected nodeId.
|
||||
- `workspace-ready`: `node.inventory` and bounded workspace read target the YAML-selected root.
|
||||
- `mdtodo-ready`: Project Management source save/probe/reindex succeeds through public HWPOD workspace ops.
|
||||
|
||||
Read [references/python-ui-node.md](references/python-ui-node.md) for the current application contract, update flow and known gaps. Read [references/workspace-mdtodo.md](references/workspace-mdtodo.md) when adding a node, binding a workspace or validating HWLAB Web MDTODO.
|
||||
|
||||
## Change Workflow
|
||||
|
||||
1. Observe the selected HWLAB node/lane, public origin, Python release metadata, Windows user/session, current node process, task/Run key, config presence and legacy runners.
|
||||
2. Update the owning spec first when node identity, workspace root, resource binding, authentication, capabilities or MDTODO source changes.
|
||||
3. Render/validate config before touching Windows. Keep nodeId, URL, workspace and retry/update settings out of generated helper code.
|
||||
4. Install or update the published Python artifact by verified SHA. Resolve the target interactive user's Windows `python.exe`, record its path/version, and use it to launch the file in that Windows session so GUI and tray are visible; use a login-start mechanism only when declared by YAML.
|
||||
5. Prove one active authority, expected version/nodeId, registration, `node.health`, `node.inventory`, bounded workspace read and structured diagnostics.
|
||||
6. Validate MDTODO through the HWLAB Web-equivalent path: source save, probe, reindex, files/tasks visible. Direct `trans cat` is only P1 diagnosis.
|
||||
7. Record source commit, artifact SHA, nodeId, workspace fingerprint/path summary, registration state, operation request/trace IDs and MDTODO source/reindex result. Never record raw Markdown or credentials by default.
|
||||
|
||||
## Stop Conditions
|
||||
|
||||
- Stop before mutation if the selected lane/source authority is unclear or stale.
|
||||
- Stop before starting a second runner if an existing process controls the same nodeId/resource.
|
||||
- Stop before MDTODO write/reindex if workspace containment is not enforced or the source can escape its declared root.
|
||||
- Treat node mismatch, auth failure, missing workspace, capability mismatch, legacy drift and source projection failure as different blockers.
|
||||
- Do not close an HWPOD issue on process health alone; use the user's original HWLAB Web/CaseRun/MDTODO entrypoint.
|
||||
|
||||
## References
|
||||
|
||||
- Python UI node contract, local files, update endpoints and drift: [references/python-ui-node.md](references/python-ui-node.md).
|
||||
- Node onboarding, workspace binding and MDTODO verification: [references/workspace-mdtodo.md](references/workspace-mdtodo.md).
|
||||
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "UniDesk HWPOD 运维"
|
||||
short_description: "运维 Python UI HWPOD 节点、连接、工作区与 MDTODO"
|
||||
default_prompt: "使用 $unidesk-hwpod-ops 调查并运维指定 HWLAB Python UI HWPOD 节点。"
|
||||
@@ -0,0 +1,64 @@
|
||||
# Python UI Node
|
||||
|
||||
## Current Source
|
||||
|
||||
- HWLAB source: `tools/hwlab-node.py` on the YAML-selected v0.3 source workspace.
|
||||
- Application: single-file Python/tkinter GUI with Windows tray, reconnect loop, rotating log and self-update.
|
||||
- Local state: `%USERPROFILE%\.hwlab\config.json`, `state.json`, `logs\hwlab-node.log`, `update\`.
|
||||
- Default public origin: `https://hwlab.pikapython.com`.
|
||||
- Update metadata: `GET /v1/hwlab-node/update?platform=windows&channel=stable¤t=<version>`.
|
||||
- Artifact: `GET /v1/hwlab-node/download/hwlab-node.py`; verify the metadata SHA before replacement.
|
||||
- Node transport: active outbound `wss://<origin>/v1/hwpod-node/ws` registration and heartbeat.
|
||||
- Node-ops contract: `hwpod-node-ops-v1`.
|
||||
|
||||
Do not copy version numbers or SHA values into long-lived instructions. Read them from the selected runtime/source during each operation.
|
||||
|
||||
## Desktop Configuration
|
||||
|
||||
The current application exposes `serverUrl`, `nodeId`, `autoConnect`, update settings and logging settings. It intentionally accepts no CLI arguments or `HWLAB_*` environment variables.
|
||||
|
||||
Run the application with the target Windows user's native interpreter. Resolve `python.exe` from the same interactive login context that owns `%USERPROFILE%\.hwlab` and the tray, then persist the selected interpreter path in the owning node profile/start declaration. `python --version`, `Get-Command python` and a tkinter import are discovery evidence; a WSL `/usr/bin/python`, SSH-side helper interpreter or hidden service account is not an acceptable runtime.
|
||||
|
||||
Treat local config as operator preference only. Platform declarations still own:
|
||||
|
||||
- node/lane and unique nodeId;
|
||||
- HWPOD resource and capability binding;
|
||||
- allowed workspace roots;
|
||||
- WebSocket/auth Secret sourceRef;
|
||||
- managed login/start policy;
|
||||
- Windows interpreter path/version and interactive user;
|
||||
- Project Management MDTODO sources.
|
||||
|
||||
## Status Evidence
|
||||
|
||||
Collect bounded, redacted facts:
|
||||
|
||||
```powershell
|
||||
$root = Join-Path $HOME ".hwlab"
|
||||
[ordered]@{
|
||||
home = $HOME
|
||||
configExists = Test-Path (Join-Path $root "config.json")
|
||||
stateExists = Test-Path (Join-Path $root "state.json")
|
||||
logExists = Test-Path (Join-Path $root "logs\hwlab-node.log")
|
||||
interactiveShell = (Get-Process explorer -ErrorAction SilentlyContinue | Measure-Object).Count
|
||||
} | ConvertTo-Json -Compress
|
||||
```
|
||||
|
||||
Read config fields only when needed and redact any unknown future Secret-bearing field. Prefer cloud `node.health`, `node.version`, `node.inventory` and `node.diagnostics` results for registration/runtime evidence.
|
||||
|
||||
## Known Gaps To Check
|
||||
|
||||
Never assume the newest published file has solved these items; inspect the selected source/version:
|
||||
|
||||
- Default nodeId may still be D601-specific.
|
||||
- Workspace operations may accept request-provided absolute paths without a configured allowlist or containment check.
|
||||
- WebSocket registration may lack a node credential even when cloud-api supports a token.
|
||||
- Capabilities may lag the cloud contract, especially apply-patch, UART write/JSON-RPC, Keil and structured blockers.
|
||||
- GUI close-to-tray is not equivalent to login persistence; a scheduled task in a non-interactive session can hide the UI/tray.
|
||||
- A legacy Bun runner may remain active under another task, Run key or runtime directory.
|
||||
|
||||
Surface each gap separately. Do not add local fallback paths to conceal it.
|
||||
|
||||
## Legacy Drift
|
||||
|
||||
Legacy evidence includes `bun.exe tools\hwpod-node.ts connect`, old IP/port cloud URLs, `hwpod-node-runtime`, and old scheduled task names. Before stopping anything, compare nodeId, cloud URL, resource binding and active hardware work. Any change that can interrupt a hardware operation requires an explicit maintenance window and `$dad-dev` workflow.
|
||||
@@ -0,0 +1,56 @@
|
||||
# Workspace And MDTODO
|
||||
|
||||
## Required Declarations
|
||||
|
||||
Add a node/workspace only through owning YAML/configRef. Keep these concepts distinct:
|
||||
|
||||
| Concept | Required fact |
|
||||
| --- | --- |
|
||||
| Desktop node | HWLAB node/lane, unique nodeId, Python artifact source, Windows pythonPath/version, managed interactive user/start policy |
|
||||
| HWPOD resource | hwpodId/resourceId, nodeId, capabilities, workspaceRootRef |
|
||||
| Workspace policy | allowed Windows roots, containment/normalization policy, read/write capabilities |
|
||||
| MDTODO source | sourceId, projectId, hwpodId, nodeId, workspaceRootRef, mdtodoRootRef |
|
||||
| Service routing | public/service node-ops configRef and Secret sourceRef |
|
||||
|
||||
For a Windows Python UI node, `workspaceRootRef` must use the Windows path visible to that process. A WSL `/mnt/<drive>/...` route may prove the same files exist, but it is not the Python node's path authority.
|
||||
|
||||
## Onboarding Sequence
|
||||
|
||||
1. Confirm the Windows path exists, is a directory and contains the intended MDTODO root.
|
||||
2. Allocate a nodeId distinct from D601 and all existing nodes.
|
||||
3. Add YAML declarations for desktop node, HWPOD resource/workspace policy and MDTODO source.
|
||||
4. Ensure the Python node enforces declared workspace roots with canonical-path containment; reject absolute paths outside them, `..`, symlink/junction escape and undeclared roots.
|
||||
5. Configure registration authentication from SecretRef without printing credentials.
|
||||
6. Install the SHA-verified Python artifact and launch in the selected interactive Windows user session.
|
||||
7. Prove cloud registration and expected capabilities.
|
||||
8. Run `node.inventory` against the declared root, then bounded `workspace.ls`/`workspace.cat` under the MDTODO root.
|
||||
9. Save/probe/reindex the Project Management source and verify files/tasks in HWLAB Web.
|
||||
|
||||
## MDTODO Acceptance
|
||||
|
||||
Use the public Project Management path and selected source:
|
||||
|
||||
1. Open `/projects/mdtodo` on the YAML-selected origin.
|
||||
2. Save the source with its declared `hwpodId`, `nodeId`, workspace root and relative MDTODO root.
|
||||
3. Probe the source and require a structured ready result.
|
||||
4. Reindex and record document/task counts plus fingerprint, not raw Markdown.
|
||||
5. Confirm direct `.md` files and their tasks are visible.
|
||||
6. When requested, launch Workbench from one task and verify the resulting task/session link.
|
||||
|
||||
The equivalent API family is `/v1/project-management/mdtodo/*`; use the repo-owned web-probe commands when available. Never make direct filesystem reads the completion evidence.
|
||||
|
||||
## Failure Classification
|
||||
|
||||
| Code family | Meaning |
|
||||
| --- | --- |
|
||||
| node-offline | Python process absent or WebSocket not registered |
|
||||
| node-id-mismatch | plan targets a different node identity |
|
||||
| node-auth | credential missing/rejected |
|
||||
| workspace-policy | root absent, outside allowlist or containment failure |
|
||||
| capability-mismatch | node cannot execute the requested public operation |
|
||||
| workspace-op | bounded operation failed inside an allowed root |
|
||||
| source-probe | Project Management could not read/parse the source |
|
||||
| source-projection | reindex or DB projection failed after source read |
|
||||
| web-visibility | API state exists but HWLAB Web does not expose it correctly |
|
||||
|
||||
Preserve requestId/traceId and node diagnostics for the failing layer. Fix the owning layer instead of adding SSH, direct filesystem, local mount or private API fallbacks.
|
||||
Reference in New Issue
Block a user