Skip to main content

Framework-neutral client runtime for WorkerTower

Project description

WorkerTower Client

Framework-neutral local runtime for consuming assignments from WorkerTower Server. Codex is one adapter; it is not part of the protocol contract.

Boundaries

Component Responsibility
Server Select projects, Subflow(子流程)Steps(步骤), roles, prompts, and task objectives
Client Persist execution evidence, renew leases, and deliver results reliably
Adapter Map the server identity and objective to framework-native prompt layers

The client never creates or extends runtime prompts. The identity layer is the exact server PromptSnapshot.content. The objective layer contains the task envelope, including constraints.output_locale. Runtime user-visible prose must come from the server assignment and use that locale. Client-generated output is limited to stable protocol and status codes.

Configuration

Install the released Client CLI(客户端命令行)from PyPI:

uv tool install workertower-client
workertower --help
workertower --version

For repository development only:

uv tool install ./client

Initialize and pair a new Worker(工作节点)with the local Community Server at http://127.0.0.1:8000:

workertower init

Select a self-hosted Community Server(社区版服务端)explicitly:

workertower init --server-url https://community.example.com

init is an idempotent Worker-first(工作节点优先)state machine. On first use it creates non-secret local configuration, generates a short-lived pairing session, and returns only a verification URL, pairing code, complete QR payload URL, and expiry. Open the URL in Server Web(服务端网页)and approve the Worker, then run the same command again:

workertower init
# Explicit but equivalent:
workertower init --resume

While approval is outstanding the status is PAIRING_PENDING. The approval page can optionally grant Device Operator(设备操作员)access to this trusted machine. After approval, the Client validates the authenticated Agent Client Profile(智能体客户端资料), calibrates the Server client key, validates capabilities, and synchronizes configuration. When Operator access was granted, init also returns all Server Projects as read-only discovery data so the local LLM can immediately offer an existing-project binding or a new-project flow. A newly paired Worker with no projects returns PAIRED_NO_PROJECTS; this is a successful state, not an error.

No Project(项目)is required to pair a Worker. After the Skill has inspected the local repository and the user confirms its proposed project JSON, create the Project and local binding together:

workertower project-create \
  --project /private/path/project.json \
  --path /local/repository

The project JSON may contain an initial_workflow object for the built-in code_maintenance_review Workflow(代码维护审查工作流). Omitting the field accepts the Server default; "initial_workflow": null explicitly opts out. The Client preserves this selection but never chooses the Workflow's Subflows(子流程)or Steps(步骤). Successful project creation returns READY plus workflow_id when a Workflow was created. The repository path remains local and is never sent as Server project configuration. The generated candidate Worker and Operator candidate credentials are generated independently and stored in separate macOS Keychain(钥匙串)items before pairing and never appear in stdout, command arguments, config, or state files. The Operator candidate is deleted when the approval does not grant that access. The retained Operator credential is read only by explicit conversational control-plane commands; scheduled execution, Claim, Adapter, Task Envelope, Heartbeat, and Completion paths can read only the Worker credential. The private device_code is held temporarily in a mode 0600 pairing record for crash recovery and deleted only after authenticated profile validation and configuration sync succeed.

Fresh bare initialization uses http://127.0.0.1:8000. Existing configuration always resumes its saved Server URL and rejects an implicit cross-Server migration. Pass --server-url https://server.example.com, or --server-url http://localhost:8000 when both self-hosted components run locally. Remote URLs require HTTPS(加密连接). Pairing currently supports the codex adapter only and returns PAIRING_ADAPTER_UNSUPPORTED for other adapters without falling back to a manual token flow. connect --token-stdin remains available only as a compatibility path for Servers that issued a legacy setup token. It validates the Framework(框架)and replaces the temporary identity with the registered Server client key before configuration synchronization. It never embeds or prints an API Token(接口令牌).

Reinstall after a protocol-version upgrade. Server and Client must both support Task Envelope schema 1.0.

Configuration files contain no credentials:

{
  "server_url": "http://127.0.0.1:8000",
  "client_instance_id": "workstation-01",
  "state_root": "~/.workertower",
  "adapter_name": "codex",
  "keychain_account": "workstation-01",
  "operator_keychain_account": "workstation-01:operator",
  "config_keychain_account": "workstation-01:config",
  "max_concurrent_assignments": 5,
  "capabilities": [
    "repository_read",
    "repository_write",
    "task_record_write",
    "git_worktree",
    "test_execute"
  ]
}

Client 0.6.2 defaults max_concurrent_assignments to 5. The effective capacity is min(Client limit, Server max_concurrent_runs) only when both sides advertise concurrent_assignments_v1; an old or incomplete Server profile fails safe to one Assignment. Override the local ceiling with the non-secret configuration field or WORKERTOWER_MAX_CONCURRENT_ASSIGNMENTS. status reports configured, Server, effective, active, and remaining capacity without exposing local repository paths.

Set WORKERTOWER_API_TOKEN or configure WORKERTOWER_KEYCHAIN_ACCOUNT. Tokens are only read through the environment or macOS Keychain credential provider. The normal execution credential reads and acknowledges configuration; it must not submit configuration changes. Use the separate optional WORKERTOWER_CONFIG_API_TOKEN or WORKERTOWER_CONFIG_KEYCHAIN_ACCOUNT credential for config:write. A copied one-time configuration token can be stored without shell history through pbpaste | workertower connect --config-token-stdin. The optional Device Operator credential uses WORKERTOWER_OPERATOR_KEYCHAIN_ACCOUNT. It is never used as a fallback for the Worker or configuration credential. After revocation, operator-access-regrant creates a separate short-lived candidate in a derived Keychain item and sends only its prefix and SHA-256 hash to the Server. Approval promotes that candidate into the Operator Keychain item without changing the Worker identity or Bindings; denial and expiry delete it. If final local cleanup is interrupted, a secret-free promoted record verifies the primary Keychain hash before retrying cleanup; an old revoked token cannot be mistaken for the new credential. The command prints the approval URL/code and polls automatically, so the user does not need to return and run a second command. --no-wait is available only for scripted one-poll workflows.

When the Server requires User Presence(用户在场), an Operator write receives 428 USER_PRESENCE_REQUIRED. The Client creates a challenge bound to the exact HTTP method, path, and raw JSON body hash, prints only its Web URL/code to stderr, polls automatically, and retries the unchanged write once with an in-memory one-time header. Reads and scheduled Worker operations never enter this flow, and the presence secret is neither returned by the Server nor stored on disk or printed.

Worker transfer uses an explicit, short-lived, single-use Transfer Ticket(迁移 票据), never the active Worker Bearer Token. The destination generates its own candidate, sends only its prefix/hash, and promotes it after a successful or idempotently repeated consume. Server-side Worker ID and Bindings are retained; the old Worker, Operator, and config:write credentials are revoked. Consumption requires --ticket-stdin, so the ticket never enters shell history or the process list. Pause the source scheduler and let its active Assignment finish before issuing the ticket. A live Lease makes consumption fail safely with WORKER_TRANSFER_ACTIVE_ASSIGNMENT; the Server never cuts off heartbeat or completion for in-progress work. An interrupted post-commit cleanup is resumed only after both the saved client_key and primary Worker Keychain hash match the secret-free local commit record; the Server consume request is not repeated. If a parent environment still injects any revoked credential, the command returns only the affected variable names under external_cleanup_required; remove those overrides before the next Worker operation. Remote Server URLs must use HTTPS. Plain HTTP is accepted only for loopback hosts such as localhost, 127.0.0.1, and ::1. The client refuses a state_root at or below ~/.workbuddy.

Production clients should obtain credentials through macOS Keychain or a daemon credential broker. Git subprocesses receive a scrubbed environment with token-, lease-, secret-, password-, credential-, and private-key-shaped values removed. The process that launches the execution Agent must apply the same boundary so the Agent never inherits the Server API token or lease secrets.

Commands

workertower --config client.json claim
workertower init
workertower init --server-url https://community.example.com
workertower --config client.json init [--resume]
workertower --config client.json project-create --project project.json --path /local/repository
workertower --config client.json connect
workertower --config client.json bind --binding-id <server-binding-id> --path /local/repository --worktree-root /local/worktrees
workertower --config client.json config-manifest
workertower --config client.json config-pull --project-id <project-id>
workertower --config client.json config-show [--project-id <project-id>]
workertower --config client.json config-change-queue --project-id <project-id> --patch patch.json --confirmed --confirmed-by <actor>
workertower --config client.json config-push
workertower --config client.json config-ack --project-id <project-id>
workertower --config client.json config-sync
workertower --config client.json config-conflict-resolve --request-id <request-id> --accept-server
workertower --config client.json heartbeat --assignment-id <id> --execution-token <token>
workertower --config client.json artifact-register --assignment-id <id> --execution-token <token> --artifact-type <type> --name <relative-name> --source <file>
workertower --config client.json artifact-register ... --review-content
workertower --config client.json complete --assignment-id <id> --execution-token <token> --result result.json
workertower --config client.json outbox-flush
workertower --config client.json outbox-retry --completion-id <id>
workertower --config client.json outbox-resolve-stale [--completion-id <id>]
workertower --config client.json reconcile
workertower --config client.json resume --assignment-id <id> --execution-token <token>
workertower --config client.json status
workertower --config client.json status --local-only
workertower --config client.json operator-status
workertower --config client.json project-list [--limit <count>]
workertower --config client.json operator-project-create --project project.json --confirmed --confirmed-by <actor>
workertower --config client.json project-update --project-id <id> --patch patch.json --config-hash <sha256> --config-revision <revision> --confirmed --confirmed-by <actor>
workertower --config client.json worker-list [--limit <count>]
workertower --config client.json worker-update --worker-id <id> --enabled <true|false> --confirmed --confirmed-by <actor>
workertower --config client.json operator-access-show --worker-id <id>
workertower --config client.json operator-access-revoke --worker-id <id> --confirmed --confirmed-by <actor>
workertower --config client.json operator-access-regrant [--no-wait] --confirmed --confirmed-by <actor>
workertower --config client.json user-presence-policy-show --worker-id <id>
workertower --config client.json user-presence-policy-update --worker-id <id> --required <true|false> --confirmed --confirmed-by <actor>
workertower --config client.json worker-transfer-create --confirmed --confirmed-by <actor>
workertower --config client.json worker-transfer-consume --ticket-stdin --confirmed --confirmed-by <actor>
workertower --config client.json binding-list [--worker-id <id>] [--project-id <id>] [--limit <count>]
workertower --config client.json binding-create --worker-id <id> --project-id <id> [--path /local/repository] --confirmed --confirmed-by <actor>
workertower --config client.json binding-update --binding-id <id> --enabled <true|false> --confirmed --confirmed-by <actor>
workertower --config client.json task-list
workertower --config client.json task-create --task task.json [--idempotency-key <key>] --confirmed --confirmed-by <actor>
workertower --config client.json task-clear-affinity --task-id <id> --confirmed --confirmed-by <actor>
workertower --config client.json run-list [--project-id <id>]
workertower --config client.json sync-conflict-list
workertower --config client.json sync-conflict-resolve --request-id <id> --accept-server --confirmed --confirmed-by <actor>
workertower --config client.json project-config-history --project-id <id>
workertower --config client.json project-sync-status --project-id <id>
workertower --config client.json pairing-show --user-code <code>
workertower --config client.json pairing-approve --user-code <code> [--grant-operator-access] --confirmed --confirmed-by <actor>
workertower --config client.json pairing-deny --user-code <code> --confirmed --confirmed-by <actor>
workertower --config client.json human-gate-show --task-id <id>
workertower --config client.json human-gate-decide --task-id <id> --decision <approve|dismiss|request_revision> [--reason <text>] --confirmed --confirmed-by <actor>
workertower legacy-export --output legacy-bundle.json
workertower --config client.json uninstall --yes

Pass a Transfer Ticket through standard input; do not put it in shell history. For a new destination, add --server-url https://community.example.com and a new --config path to the same --ticket-stdin command.

uninstall --yes is a destructive local reset. Stop and remove every external cron / framework trigger first. The command acquires the Client locks, removes all recorded Git Worktrees even when dirty, deletes Client configuration, current and default legacy state, and the configured Worker, Operator, and config:write Keychain items, including any pending Operator re-grant and Worker-transfer candidate items. It preserves project repositories, branches, commits, and Server records. A custom state_root is cleaned by known Client-owned entry rather than blindly deleting unknown sibling files. Environment-injected credentials and scheduler definitions are reported by name for removal through their external owner. The executable and Skill remain installed; remove those packages separately through their original installer only when full software removal is requested.

complete accepts a semantic Result Draft(结果草稿)and deterministically fills schema_version, assignment ID, output locale, start/completion timestamps, and the registered Artifact Index(产物索引)before validating and writing the canonical request to outbox/pending. The LLM supplies only outcome, summary, Step-specific outputs, and any explicit remote artifact references. Retries reuse the same completion_id. Transient failures remain pending; permanent failures and exhausted delivery retries move to outbox/dead-letter. An explicit Server rejection with state_changed=false moves to outbox/rejected: deterministic-field failures are rebuilt under a new Completion ID with a persisted supersession link, while semantic failures return retry_action=repair_result for at most two LLM repairs. Exhaustion returns retry_action=stop_for_human. Network/timeout delivery returns retry_action=retry_unchanged and never mutates the queued request. Persistent dead-letter records are Assignment-scoped. The affected Assignment retains its capacity slot and local resource ownership and reports COMPLETION_DEAD_LETTER_REQUIRES_ATTENTION, while unrelated Assignments may still be claimed when negotiated capacity remains. For a completion rejected with a stale assignment or lease code, claim queries authoritative assignment state and, only when lease_active=false is confirmed, moves it to outbox/abandoned, releases the local execution session and resource, and continues. This is not a successful receipt; the complete rejection and resolution evidence remain available for audit. An unavailable, ambiguous, or active lease leaves only that Assignment blocked. outbox-resolve-stale exposes the same fail-closed reconciliation for an operator-selected Completion ID. Before enqueueing, the client validates the result against the pinned outcome, locale, and artifact contract. Every produced client:// artifact must exist as a regular local file and match its required SHA-256 digest.

CLI failures use a secret-safe JSON error contract with stable error_code, stage, operation, retry_class, retryable, retry_action, locally generated remediation, and exit_code fields. Filesystem diagnostics expose only a path_kind and errno name, never a raw local path. Server diagnostics retain well-formed UUID request IDs and only schema-allowlisted field-error path, code, and owner values. Server-supplied stage is ignored; Server-supplied remediation and field_errors.message are never copied. Unknown remote error codes normalize to PROTOCOL_ERROR. Tokens, Device Codes, lease data, and arbitrary remote details are never copied into error output or Outbox diagnostics.

The HTTP transport accepts at most 16 MiB for a successful JSON response and 1 MiB for an error response. It fails closed with RESPONSE_TOO_LARGE before parsing an oversized body. Same-origin redirects remain supported; a redirect to a different scheme, host, or port is rejected before credentials or request content can be forwarded. Redirect response bodies are also bounded and every handled response is closed on success or failure.

artifact-register always records safe deterministic metadata (artifact_id, type, relative name, canonical URI, digest, size, and inferred media type). It streams the copy and SHA-256 calculation instead of loading an ordinary Artifact into memory as one byte string. The local last line of defense allows at most 256 MiB per file, 1 GiB and 256 files per Assignment, while preserving at least 256 MiB of free disk. Structured JSON Artifacts that require schema validation are additionally limited to 16 MiB before hashing or parsing. Artifact contents are not uploaded by default. Use --review-content only when the type is both required by the selected outcome and listed in the pinned Completion Contract's reviewable_artifact_types; the Client then fail-closed validates a non-empty, at-most-256-KiB UTF-8 Markdown, text, or object/array JSON document and keeps its exact text for the Server Human Gate(人工门禁). The command never echoes the inline body.

claim first retries pending completions, pushes only explicitly confirmed local configuration changes, compares Server Manifest(服务端清单)revision and SHA-256 hashes, pulls changed configuration snapshots, and acknowledges the applied revision. Only then can it claim work. A transient sync failure or unresolved configuration conflict prevents Claim(领取)instead of running with ambiguous configuration.

config-change-queue is the only local configuration write entrypoint. It requires an explicit --confirmed marker and records the actor separately from runtime credentials. Scheduled runs can deliver existing confirmed records but cannot create or confirm a change. A 409 Conflict(冲突) is retained under config-sync/changes/conflicts for the user to resolve; it is never silently merged or overwritten. Every later sync queries /v1/config-sync/changes/{request_id}. A remote accept_server resolution triggers an automatic pull, acknowledgment, and local archive before Claim(领取)can continue. An explicit local resolution first closes the matching Server conflict with the separate config:write credential. The explicit local config-conflict-resolve --accept-server command remains available.

The Client hashes the canonical object containing both config_schema_version and the complete config snapshot. It uses UTF-8 JSON with sorted keys, compact separators, ensure_ascii=false, no trailing newline, and the sha256: prefix. Comparing only the inner configuration object is invalid.

claim persists its Wake ID before the network call and reuses it after a lost response. It reconciles old local records before requesting new work. An assigned response includes a local execution_token; retain it for this wake's Client commands but never place it in Task Envelope, source code, reports, or artifacts. It also includes an artifact_staging_path outside the Worktree; generate reports there and register them from that path. A Step with workspace_mutation=preserve must not write generated files into execution_path.

reconcile compares local active runs with the authoritative server assignment status. Active leases return the RESUME action; terminal or lost leases return STOP. Resume also compares the local Task Envelope with the authoritative Server envelope_digest; missing or mismatched integrity data returns INTEGRITY_FAILURE. The client does not choose another project or role. Concurrent claim calls may each receive one Assignment until the negotiated capacity is full. The short global Claim lock protects only capacity recheck, Server Claim, and durable admission; setup and execution remain outside it. busy returns without an invocation or execution token when capacity is full or the same Assignment already has an operation in progress. resume performs the same online check and recreates the workspace resolution only when the caller supplies the matching local execution token. If an Agent loses that token, it must not take over an active lease; Server expiry and a later Claim(领取)provide safe recovery.

init and online status discover Worker-authorized Project Bindings from the authenticated Server endpoint. BINDING_REQUIRED lists only non-sensitive project metadata. With Device Operator access they also report Operator status and all Server Projects for onboarding discovery. status --local-only never accesses credentials or the network and validates existing Git roots locally.

bind first verifies that the opaque binding belongs to the authenticated Worker and is enabled, then stores its mapping to a local Git repository root and synchronizes configuration. The next Claim is blocked unless remote authorization and every required local mapping are READY. binding-create can authorize any Worker. When --path is supplied, the target must be the current Worker: the Client validates the Git root before mutating Server state, then creates the Server Binding, stores the local mapping, and synchronizes configuration. If local persistence fails after Server success, the result is AUTHORIZED_LOCAL_BIND_REQUIRED with the exact safe bind recovery action; it never pretends the Server mutation was rolled back. The local path never enters server configuration or the Task Envelope. Claim persists the resolved workspace separately from the two framework prompt layers. When constraints.worktree_required is true (the Server default), the client creates or resumes a deterministic Git worktree keyed by objective.task_id and the binding. Every Step(步骤,协议名 Pipeline Node)assignment for that Task reuses the same path, branch, and first base_commit, so uncommitted handoff changes remain visible. When it is explicitly false, the bound path must be a Git root and execution is strictly read-only: Client snapshots HEAD and a content-sensitive status digest and rejects completion after any Git-visible change. Claim output names these values explicitly as execution_path and workspace_record_path. The worktree base defaults to parameters.default_branch from Server. Pass --default-branch <name> to bind only when a client-local override is needed.

Local state

bindings/
onboarding/pairing.json  # temporary, private, removed after successful pairing
config-sync/mirrors/<project-id>.json
config-sync/changes/pending/<request-id>.json
config-sync/changes/acknowledged/<request-id>.json
config-sync/changes/conflicts/<request-id>.json
config-sync/changes/rejected/<request-id>.json
config-sync/changes/resolved/<request-id>.json
config-sync/acknowledgements/<project-id>.json
task-workspaces/<task-binding-hash>.json
assignments/<assignment-id>/envelope.json
assignments/<assignment-id>/control.json
assignments/<assignment-id>/execution.json
assignments/<assignment-id>/workspace.json
claims/pending.json
runs/<assignment-id>/manifest.json
runs/<assignment-id>/journal.jsonl
runs/<assignment-id>/result.json
runs/<assignment-id>/artifact-index.json
runs/<assignment-id>/completion-repair.json
runs/<assignment-id>/artifacts/
guards/no-push/pre-push
worktrees/<task-slug>-<task-binding-hash-prefix>/
outbox/pending/
outbox/acknowledged/
outbox/rejected/
outbox/dead-letter/
outbox/abandoned/
declines/pending/
declines/acknowledged/
declines/rejected/
resources/owners/
resources/assignments/

JSON state uses atomic replacement and private file permissions. Journal events use append-only JSON Lines. The short Claim admission section uses one inter-process File Lock(进程间文件锁); Outbox delivery, finalization, decline, and execution operations use per-Assignment locks. Persistent resource ownership prevents two Assignments from sharing one Task Worktree(任务工作树)or direct repository. The durable execution session survives the short CLI process: only the wake holding that Assignment's execution_token can heartbeat, register artifacts, resume, or complete. Its handoff is persisted as prepared before the assigned response is written and changed to delivered only after stdout is flushed, so a crash can replay the same Wake ID(唤醒编号)and token without creating a second owner.

The client verifies the canonical Task Envelope SHA-256 and the embedded PromptSnapshot content SHA-256 on claim, persistence, load, and immediately before Adapter mapping. Lease and control data never enter either prompt layer.

workspace.json records repository_path, execution_path, kind, Task ID(任务编号), the deterministic worktree branch, base_ref, and base_commit; direct read-only records also include baseline_head and baseline_status_digest. The Client installs a worktree-local pre-push guard when Push(推送)is forbidden and validates commit, merge, changed-file, and patch-line constraints before completion. The guard is a bypassable accidental-push Guardrail(防误操作护栏), not strong enforcement against git push --no-verify; strong enforcement requires a controlled Git Gateway(Git 网关)or OS / network Sandbox(操作系统/网络沙箱). Local paths remain client-only and are not inserted into the saved Task Envelope or adapter prompt payload.

Legacy export

legacy-export reads the former ai-team-config.json and ai-team-state directories without modifying them or contacting Server:

workertower legacy-export \
  --legacy-config ~/.codex/ai-team-config.json \
  --legacy-state-root ~/.codex/ai-team-state \
  --output ./legacy-bundle.json

The versioned bundle contains projects, client-local bindings, human tasks, backlogs, and historical run/artifact metadata. Repository paths appear only in client_bindings; artifact content and local artifact paths are not exported. Credential-, token-, lease-, and secret-shaped fields are removed.

The bundle declares source.authority = "none" and source.scheduler_state_imported = false. Old decisions, scheduler scores, locks, leases, and active-run ownership never become new assignments or Server authority. Project configuration snapshots require explicit review before any future import.

License(许可证)

本仓库采用 MIT License(MIT 许可证)。官方云订阅能力和企业版扩展不包含在本开源仓库中。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

workertower_client-0.6.2.tar.gz (229.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

workertower_client-0.6.2-py3-none-any.whl (172.5 kB view details)

Uploaded Python 3

File details

Details for the file workertower_client-0.6.2.tar.gz.

File metadata

  • Download URL: workertower_client-0.6.2.tar.gz
  • Upload date:
  • Size: 229.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for workertower_client-0.6.2.tar.gz
Algorithm Hash digest
SHA256 3e05062770d1b3659004004402d68f7147419b3ea9247db6615213d33fdddac6
MD5 5d3d9fb26b6b3ef6a6521460b90db0b8
BLAKE2b-256 46d8d562b8835530218df8aad6274ad7a85f28ab62d9d2a4c62e644b4bc07c59

See more details on using hashes here.

File details

Details for the file workertower_client-0.6.2-py3-none-any.whl.

File metadata

  • Download URL: workertower_client-0.6.2-py3-none-any.whl
  • Upload date:
  • Size: 172.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for workertower_client-0.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ecc932a7b4135e4e5bded040fa571d8f255d2e66fa94b76e937da62f8ff4d877
MD5 dac17e3d5fbfe2df486fe40454e274be
BLAKE2b-256 2c1fbc0a516868a5d08f9138471025e1e3d85a86f872d387634f57a2c6532a10

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page