12 KiB
name, description, version
| name | description | version |
|---|---|---|
| device-pod-cli | Use the HWLAB v0.2 internal device-pod CLI from a HWLAB code agent runner to operate authorized Device Pods through cloud-api REST, leases, hwlab-device-pod, gateway, and device-host-cli. | 0.2.0-rest |
Device Pod CLI
Skill(cli-spec)
Scope: this skill is only for HWLAB-internal code agent runners assembled from a HWLAB ResourceBundleRef, such as AgentRun v0.1 jobs for the G14 DEV, PROD, or v0.2 lanes. It does not apply to external UniDesk developer workspaces or third-party machines.
Use this skill when the task mentions device-pod-cli, device-pod, device-host-cli, Keil build/download through a Device Pod, debug probe control, workspace operations, or I/O probe reads such as UART boot logs.
Canonical AgentRun skill location: .agents/skills/device-pod-cli/SKILL.md inside the current materialized workspace. The source manifest is skills/device-pod-cli/SKILL.md in the same Git commit as the run. Do not use /app/skills, /root/.agents/skills, /home/ubuntu/.agents/skills, ConfigMaps, host paths, or copied workspace skill directories as substitutes; those locations cause stale instructions.
Runtime Contract
- The stable runner entrypoint is
hwpod. Ifhwpodis missing from PATH, reporthwpod_unavailableas a runner assembly blocker; do not switch to/app/skills, generic shell, or an old diagnostic image. - The canonical implementation is
tools/device-pod-cli.mjsfrom the same ResourceBundleRef commit, exposed through thehwpodtool alias. - All commands emit JSON. A command with no output is a failure.
- Formal v0.2 mode is cloud-api authority: the CLI calls
/v1/device-pods...REST APIs and must not read.device-pod/*.jsonas the source of truth for gateway session, workspace root, probe UID, UART port, or host CLI. - Server-side profile, grant, lease, job authority, and profile hash are owned by
hwlab-cloud-api;hwlab-device-podanddevice-host-cliexecute only after cloud-api authorization.
Configuration
In HWLAB code-agent runners, do not pass API URLs or session tokens by hand. WEB / AgentRun assembles the runtime context and credential before the runner starts:
HWLAB_RUNTIME_API_URL=<assembled-current-runtime-api-or-web-proxy>
HWLAB_RUNTIME_NAMESPACE=<assembled-current-namespace>
HWLAB_RUNTIME_LANE=<assembled-current-lane>
HWLAB_RUNTIME_ENDPOINT_LOCKED=1
HWLAB_DEVICE_POD_SESSION_TOKEN=<assembled-device-pod-session-token>
hwpod automatically locates cloud-api from the assembled runtime env and automatically uses HWLAB_DEVICE_POD_SESSION_TOKEN. When HWLAB_RUNTIME_ENDPOINT_LOCKED=1, passing --api-base-url, --api-url, --cloud-api-url, or --base-url is a hard error. This prevents stale trace examples or model guesses from overriding the current cluster/lane.
--api-base-url and --session-token are local-debug-only options outside locked HWLAB runners. Do not use them in normal DS / AgentRun / Cloud Workbench flows.
Primary Commands
List visible Device Pods through cloud-api authority:
hwpod profile list
Show one visible Device Pod status and redacted server profile summary:
hwpod profile show --pod-id device-pod-71-freq
hwpod health --pod-id device-pod-71-freq
Start every Device Pod task or resumed context with bootsharp so the agent sees the current workspace tree and AGENTS.md through the formal REST path:
hwpod bootsharp --pod-id <devicePodId>
hwpod <devicePodId>:workspace:/ bootsharp
For the D601 F103 v2 board, the registered devicePodId is D601-F103-V2; its server-side profile points to F:\Work\D601-HWLAB, Keil project projects/01_baseline/Projects/MDK-ARM/atk_f103.uvprojx, target USART, C:\Keil_v5\UV4\UV4.exe, and UART COM9 at 115200.
Diagnose auth, grant, lease, and gateway blockers without touching local profiles:
hwpod doctor --pod-id device-pod-71-freq
Acquire and inspect a lease for mutating jobs:
hwpod lease acquire --pod-id device-pod-71-freq --reason "build smoke"
hwpod lease current --pod-id device-pod-71-freq
hwpod lease release --pod-id device-pod-71-freq --lease-token <lease-token>
Run read-only workspace, debug, and I/O jobs:
hwpod device-pod-71-freq:workspace:/ ls
hwpod device-pod-71-freq:workspace:/src rg main
hwpod device-pod-71-freq:workspace:/ rg --pattern "Programming Done|Verify OK|Application running|Error" --path projects/01_baseline/captures
hwpod device-pod-71-freq:debug-probe chip-id
hwpod device-pod-71-freq:io-probe:/uart/1 read --duration-ms 5000
Run mutating jobs only with reason and lease token when required by cloud-api:
hwpod \
device-pod-71-freq:workspace:/ apply-patch \
--reason "DEV edit" --lease-token <lease-token> < patch.diff
hwpod \
device-pod-71-freq:workspace:/ put User/new.c \
--reason "DEV edit" --lease-token <lease-token> < file
hwpod \
device-pod-71-freq:workspace:/ rm User/old.c --missing-ok \
--reason "remove obsolete source" --lease-token <lease-token>
hwpod \
device-pod-71-freq:workspace:/ rmdir User/empty \
--reason "remove empty folder" --lease-token <lease-token>
hwpod \
device-pod-71-freq:workspace:/ keil add-source User/new.c --group User \
--reason "sync Keil project" --lease-token <lease-token>
hwpod \
device-pod-71-freq:workspace:/ keil remove-source User/old.c \
--reason "sync Keil project" --lease-token <lease-token>
hwpod \
device-pod-71-freq:workspace:/ build start \
--reason "build smoke" --lease-token <lease-token>
hwpod \
device-pod-71-freq:debug-probe download start \
--reason "DEV smoke" --lease-token <lease-token>
hwpod \
device-pod-71-freq:debug-probe reset \
--reason "reset smoke" --lease-token <lease-token>
hwpod \
device-pod-71-freq:io-probe:/uart/1 write "AT" \
--reason "UART write smoke" --lease-token <lease-token>
hwpod \
device-pod-71-freq:io-probe:/uart/1 jsonrpc gpio.read \
--params-json '{"pin":"PB5"}' --expect-result-field value \
--reason "UART JSON-RPC smoke" --lease-token <lease-token>
Inspect or cancel jobs through cloud-api:
hwpod job status --pod-id device-pod-71-freq <jobId>
hwpod job output --pod-id device-pod-71-freq <jobId>
hwpod job cancel --pod-id device-pod-71-freq <jobId>
Selector aliases also support job status/output/cancel after build/download:
hwpod device-pod-71-freq:workspace:/ build status <jobId>
hwpod device-pod-71-freq:debug-probe download output <jobId>
Use the canonical hwpod job output --pod-id <devicePodId> <jobId> form when in doubt. Selector aliases are convenience forms only for cloud-api job ids such as job_devicepod_*; host-side Keil subjobs still use build status <hostJobId> or download status <hostJobId> as nested device-host actions.
Removed Legacy Path
profile create is removed from formal v0.2 mode. If a profile is missing or wrong, an admin must update cloud-api with the admin Device Pod APIs and then grant users. The CLI returns legacy_profile_create_removed instead of creating .device-pod/<devicePodId>.json.
Do not treat local files such as .device-pod/device-pod-71-freq.json or DEVICE_POD_PROFILE_DIR as authority. They are ignored by the formal CLI and may only exist as obsolete caches or hardware-host bootstrap artifacts.
Operation Rules
- Use
hwpod/device-pod-clifirst for workspace, build, download, reset, UART, and debug-probe tasks. - After selecting a pod or resuming context, run
bootsharp --pod-id <devicePodId>before edits, build, or download. - Prefer
workspace apply-patchfor source edits. Useworkspace putonly for intentional whole-file writes or new files, because it bypasses hunk-level conflict detection. - For regex searches with spaces, pipes, or multiple path tokens, prefer explicit
rg --pattern <regex> --path <workspaceRel>or--pattern-b64 <base64>instead of positional shell parsing. - If apply-patch fails, read the returned
patchHint, re-read the current file withworkspace catorworkspace rg, and retry a smaller exact-context hunk before using whole-file write. - Do not start by calling
/app/tools/hwlab-gateway-tran.mjs, Windows-side Keil skills, serial-monitor skills,keil-cli.py, or generic shell when the Device Pod REST path is available. - If the CLI returns an auth, grant, lease, executor, or gateway blocker, fix that named blocker in the cloud-api/device-pod path; do not bypass the profile with generic gateway shell.
- The server-side profile already carries
hostWorkspaceRoot,projectWorkspace,debugInterface.uv4Path, probe UID, UART port, and gateway route. Letcloud-api -> hwlab-device-pod -> device-host-cliapply those values. - Keep I/O selectors as strict path tokens, for example
device-pod-71-freq:io-probe:/uart/1 read; do not split/uart/1across argv. - Use
--dry-runto inspect the REST job request without dispatching it.
Host Asset Bootstrap
The packaged Windows host CLI asset remains /app/skills/device-pod-cli/assets/device-host-cli.mjs. Upload it only when cloud-api/gateway dispatch reaches a Windows host and reports that tools\device-host-cli.mjs is missing or broken.
Do not upload or recreate runner-side .device-pod/*.json as the formal profile source. The profile must come from cloud-api. Host-side profile snapshots, when needed, are written by hwlab-device-pod from the cloud-api-provided server profile before invoking device-host-cli.
Safety
- Mutating operations require a human/business reason and may require an active lease. Cloud-api is the enforcement point; the CLI only forwards
reasonandleaseToken. hwlab-gatewayis transport only. Do not add a genericcmdoperation todevice-pod-cli; add a named Device Pod operation instead.SOURCE,LOCAL,DRY-RUN, fixture data, and local profile files cannot be reported asDEV-LIVEhardware evidence.
Manual Tests
T1
阅读 .agents/skills/device-pod-cli/SKILL.md,然后用 cli 手动测试以下内容:在未设置 HWLAB_RUNTIME_* / HWLAB_DEVICE_POD_* 装配环境时运行 profile list,确认输出 JSON 且错误码为 runtime_endpoint_required,没有静默 fallback 到旧 DEV 入口。
T2
阅读 .agents/skills/device-pod-cli/SKILL.md,然后用 cli 手动测试以下内容:在 WEB / AgentRun 已装配 HWLAB_RUNTIME_API_URL、HWLAB_RUNTIME_NAMESPACE、HWLAB_RUNTIME_LANE、HWLAB_RUNTIME_ENDPOINT_LOCKED=1 和 HWLAB_DEVICE_POD_SESSION_TOKEN 的真实 runner 中运行 profile list、profile show --pod-id <devicePodId>、doctor --pod-id <devicePodId>,确认 CLI 自动定位当前 runtime,输出来自 cloud-api authority,并且没有泄露 gatewaySessionId、hostWorkspaceRoot、probe UID 或 UART port。
T3
阅读 .agents/skills/device-pod-cli/SKILL.md,然后用 cli 手动测试以下内容:创建本地 .device-pod/<devicePodId>.json,写入假的 gatewaySessionId,再运行 profile list 和 selector --dry-run;确认 JSON 输出标记 localProfileAuthority=false 且没有读取本地 fake route。
T4
阅读 .agents/skills/device-pod-cli/SKILL.md,然后用 cli 手动测试以下内容:运行 profile create --pod-id <devicePodId>,确认返回 legacy_profile_create_removed,并提示使用 cloud-api admin API 管理服务端 profile/grant。
T5
阅读 .agents/skills/device-pod-cli/SKILL.md,然后用 cli 手动测试以下内容:运行 workspace put/rm/rmdir/keil 和 io-probe jsonrpc 的 --dry-run,确认 JSON plan 中 intent 分别为 workspace.put、workspace.rm、workspace.rmdir、workspace.keil、io.uart.jsonrpc,且 contentB64、text、patch 不以原文泄露。
T6
阅读 .agents/skills/device-pod-cli/SKILL.md,然后用 cli 手动测试以下内容:在 HWLAB_RUNTIME_ENDPOINT_LOCKED=1 的真实 runner 中额外传入 --api-base-url、--api-url、--cloud-api-url 或 --base-url,确认返回 runtime_endpoint_manual_url_forbidden,从而证明 DS、旧 trace 或人工命令不能覆盖 WEB / AgentRun 装配的当前集群路径。