You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build dygo Control, a remote operator CLI for running and administering a deployed dygo system.
The executable is dygoctl. It is separate from the existing dygo framework and project CLI, but it lives in the same repository and release process.
The first-run experience starts with:
dygoctl setup
The setup wizard asks for the deployment URL, verifies the deployment, opens the correct Studio authentication page, completes CLI authorization, stores the context and credential safely, and confirms that the operator can use the deployment.
Product boundary
dygo and dygoctl serve different users:
dygo framework development, local project files, metadata, database lifecycle, and runtime processes
dygoctl remote business and system operations through an authenticated deployment API
Keep both binaries in this repository so the server, client, authentication contracts, API envelopes, and releases can evolve together.
dygoctl must not:
require a dygo project checkout;
discover a local project root;
connect directly to PostgreSQL;
read deployment secret files;
import Business App or framework implementation packages to perform remote work;
create a second permission or business-operation path.
Studio and dygoctl must use the same server APIs, permission engine, Activity behavior, and Audit Log behavior.
Related work
Build the platform CLI #1 tracks the existing framework and project CLI. It does not own the remote operator CLI.
This issue defines the dygo Control product and integration shape. Related authentication and Studio work can ship as linked subtasks without being duplicated here.
Repository shape
Start with a second binary in the current Go module:
cmd/
dygo/
main.go
dygoctl/
main.go
internal/
cli/ existing framework and project CLI
operatorcli/ dygo Control command tree and terminal behavior
apiclient/ authenticated deployment HTTP client
Keep the API client internal until external Go consumers need a stable public client contract.
Setup wizard
Interactive flow
dygoctl setup performs these steps:
Explain that dygo Control connects to an existing deployment.
Ask for the deployment URL.
Normalize the URL and remove an unnecessary trailing slash.
Require HTTPS for remote deployments. Permit HTTP only for an explicit localhost development context.
Call a public health or discovery endpoint.
Confirm that the endpoint is a dygo deployment.
Read the server version and supported capabilities.
Detect an incompatible client and server before authentication.
Suggest a context name from the deployment host.
Ask the operator to confirm or change the context name.
Start a short-lived CLI device-authorization request.
Open the deployment's Studio authorization URL in the default browser.
Print the URL and one-time code so setup still works when the browser cannot open.
Let Studio redirect an unauthenticated operator to /login and return them to the authorization page after sign-in.
Show the requested CLI access and target deployment in Studio.
Require the operator to approve or deny the request.
Poll the token endpoint with a bounded interval until approval, denial, expiry, or cancellation.
Store the approved credential in the operating-system credential store.
Store only non-secret context configuration in the dygo Control config file.
Call the current-user endpoint with the new credential.
Print the context, server, authenticated user, and a successful connection result.
Example terminal flow:
$ dygoctl setup
Deployment URL: https://erp.example.com
Context name [erp-example]:
Open this page to authorize dygo Control:
https://erp.example.com/cli/authorize
One-time code: HAPY-DYGO
Waiting for authorization...
Connected.
Context: erp-example
Server: https://erp.example.com
User: operator@example.com
Setup options
Support options that keep the wizard scriptable without bypassing human authorization:
Do not add a password flag. Do not accept a password through command history or a config file.
Automation uses a service account or token flow defined with #70. It does not automate a human browser session.
Existing contexts
If the context already exists:
show its current URL;
refuse a silent replacement;
ask before changing the URL;
revoke or preserve the old credential according to the operator's explicit choice;
never send an existing credential to a newly entered host before the host is confirmed.
Authentication model
Use browser-assisted device authorization for human operators.
Studio already owns interactive user authentication. The CLI must reuse that surface so password, MFA, SSO, and future identity-provider rules stay in one place.
The CLI credential must:
be an opaque random value;
be stored only as a digest on the server;
be stored in the operating-system credential store on the client;
use Authorization: Bearer for API requests;
identify its user, context, credential type, and device name;
have creation, expiry, last-used, status, and revocation data;
inherit the user's roles and Permissions;
support narrower access without granting access that the user does not have;
never appear in Logs, errors, shell output, Activity, Audit Logs, or the non-secret context file.
Device authorization requests must:
expire quickly;
use a one-time human-readable code;
bind approval to the correct deployment and requesting client;
rate-limit public initiation and polling endpoints;
stop polling after approval, denial, expiry, terminal cancellation, or a bounded timeout;
prevent reuse after completion;
record safe security events for request, approval, denial, use, and revocation.
Add a Studio route such as /cli/authorize. An unauthenticated visitor must pass through /login and return to the pending request. The approval page must show the deployment, user, CLI name, requested access, creation time, and expiry.
Context and credential commands
dygoctl context list
dygoctl context add <name> --url <url>
dygoctl context use <name>
dygoctl context show
dygoctl context remove <name>
dygoctl auth login
dygoctl auth whoami
dygoctl auth logout
dygoctl health
dygoctl version
dygoctl capabilities
Use context for a remote deployment. Do not reuse the existing --env meaning. The framework CLI uses environment names to select local project configuration.
Planned operator command surface
Users, roles, and sessions
dygoctl user list
dygoctl user show <user>
dygoctl user invite <email>
dygoctl user enable<user>
dygoctl user disable <user>
dygoctl role list
dygoctl role show <role>
dygoctl role assign <role> --user <user>
dygoctl role revoke <role> --user <user>
dygoctl session list
dygoctl session revoke <session>
These commands depend on the purpose-built management APIs from #73 and #74. Do not grant generic access to sensitive session Records.
Business Records
dygoctl record list crm/contact
dygoctl record show crm/contact CNT-00042
dygoctl record create crm/contact --data contact.json
dygoctl record update crm/contact CNT-00042 --set status=active
dygoctl record delete crm/contact CNT-00042
Use the normal Record API and permission engine. Support filters, sorting, pagination, selected Fields, structured input, stable output, and idempotency for retryable writes.
Jobs and Schedules
dygoctl job list
dygoctl job show crm/send-welcome
dygoctl job execution list
dygoctl job execution show <execution>
dygoctl job execution run crm/send-welcome --payload payload.json
dygoctl job execution retry <execution>
dygoctl job execution cancel <execution>
dygoctl schedule list
dygoctl schedule show <schedule>
dygoctl schedule enable<schedule>
dygoctl schedule disable <schedule>
dygoctl schedule run <schedule>
Operational visibility
dygoctl log list
dygoctl log show <log>
dygoctl log tail
dygoctl activity list
dygoctl audit list
dygoctl audit show <event>
Later phases can add maintenance-mode controls and other deployment operations after the server has safe, explicit APIs for them.
Output and automation contract
The operator CLI must support:
concise human-readable tables by default;
stable JSON output for scripts and agents;
consistent pagination controls;
documented exit codes;
request and correlation identifiers when the server supplies them;
stdout for command results;
stderr for prompts, warnings, progress, and diagnostics;
no ANSI formatting when output is not a terminal or when color is disabled;
redaction of credentials, secrets, protected Fields, and sensitive session data.
Do not implement a local-only dry run for remote writes. A remote --dry-run is valid only when the server returns the authoritative plan and applies the same Permission checks as the real operation.
Write safety
Before a material or destructive write, show:
Context: erp-production
Server: https://erp.example.com
Actor: operator@example.com
Action: Disable user user@example.com
Require confirmation unless an approved non-interactive contract exists. --yes can skip a prompt, but it cannot bypass authentication, Permissions, server validation, protected-environment rules, or an unavailable authoritative plan.
Every material write must produce the same Activity or Audit Log evidence as the equivalent Studio action.
Initial delivery phases
Phase 1: foundation and setup
Add the dygoctl binary and operator CLI root.
Add context storage and selection.
Add public deployment discovery and capability checks.
Design maintenance mode and other privileged deployment APIs.
Keep raw SQL, secret-value retrieval, direct database access, process restart, database drop, schema prune, and remote migration out of scope until each operation has a reviewed server-side safety contract.
Acceptance criteria for the foundation issue
dygoctl builds as a separate binary from this repository.
dygoctl works without a dygo project checkout or local database configuration.
dygoctl setup collects and validates a deployment URL.
Setup verifies server identity, version, and capabilities before authentication.
Setup creates or updates a named remote context without silently replacing an existing target.
Setup opens Studio for browser-assisted authorization and provides a manual URL and one-time code fallback.
Studio returns the user to the CLI approval page after login.
The authorization request expires and cannot be reused.
Approval creates an individually revocable CLI credential.
The server stores only a credential digest.
The client stores the raw credential in the operating-system credential store.
The context file contains no raw credential or password.
auth whoami proves the selected context and authenticated user.
auth logout revokes the current CLI credential and removes its local copy.
CLI requests use the same Permission engine as Studio and other HTTP clients.
Material writes identify the context, server, actor, and action before confirmation.
Sensitive values do not appear in stdout, stderr, Logs, errors, Activity, or Audit Logs.
Human output and JSON output have defined, stable contracts.
Client and server incompatibility fails with an actionable upgrade message.
Goal
Build dygo Control, a remote operator CLI for running and administering a deployed dygo system.
The executable is
dygoctl. It is separate from the existingdygoframework and project CLI, but it lives in the same repository and release process.The first-run experience starts with:
The setup wizard asks for the deployment URL, verifies the deployment, opens the correct Studio authentication page, completes CLI authorization, stores the context and credential safely, and confirms that the operator can use the deployment.
Product boundary
dygoanddygoctlserve different users:Keep both binaries in this repository so the server, client, authentication contracts, API envelopes, and releases can evolve together.
dygoctlmust not:Studio and
dygoctlmust use the same server APIs, permission engine, Activity behavior, and Audit Log behavior.Related work
This issue defines the dygo Control product and integration shape. Related authentication and Studio work can ship as linked subtasks without being duplicated here.
Repository shape
Start with a second binary in the current Go module:
cmd/ dygo/ main.go dygoctl/ main.go internal/ cli/ existing framework and project CLI operatorcli/ dygo Control command tree and terminal behavior apiclient/ authenticated deployment HTTP clientKeep the API client internal until external Go consumers need a stable public client contract.
Setup wizard
Interactive flow
dygoctl setupperforms these steps:/loginand return them to the authorization page after sign-in.Example terminal flow:
$ dygoctl setup Deployment URL: https://erp.example.com Context name [erp-example]: Open this page to authorize dygo Control: https://erp.example.com/cli/authorize One-time code: HAPY-DYGO Waiting for authorization... Connected. Context: erp-example Server: https://erp.example.com User: operator@example.comSetup options
Support options that keep the wizard scriptable without bypassing human authorization:
Do not add a password flag. Do not accept a password through command history or a config file.
Automation uses a service account or token flow defined with #70. It does not automate a human browser session.
Existing contexts
If the context already exists:
Authentication model
Use browser-assisted device authorization for human operators.
Studio already owns interactive user authentication. The CLI must reuse that surface so password, MFA, SSO, and future identity-provider rules stay in one place.
The CLI credential must:
Authorization: Bearerfor API requests;Device authorization requests must:
Add a Studio route such as
/cli/authorize. An unauthenticated visitor must pass through/loginand return to the pending request. The approval page must show the deployment, user, CLI name, requested access, creation time, and expiry.Context and credential commands
Use
contextfor a remote deployment. Do not reuse the existing--envmeaning. The framework CLI uses environment names to select local project configuration.Planned operator command surface
Users, roles, and sessions
These commands depend on the purpose-built management APIs from #73 and #74. Do not grant generic access to sensitive session Records.
Business Records
Use the normal Record API and permission engine. Support filters, sorting, pagination, selected Fields, structured input, stable output, and idempotency for retryable writes.
Jobs and Schedules
Operational visibility
Later phases can add maintenance-mode controls and other deployment operations after the server has safe, explicit APIs for them.
Output and automation contract
The operator CLI must support:
Do not implement a local-only dry run for remote writes. A remote
--dry-runis valid only when the server returns the authoritative plan and applies the same Permission checks as the real operation.Write safety
Before a material or destructive write, show:
Require confirmation unless an approved non-interactive contract exists.
--yescan skip a prompt, but it cannot bypass authentication, Permissions, server validation, protected-environment rules, or an unavailable authoritative plan.Every material write must produce the same Activity or Audit Log evidence as the equivalent Studio action.
Initial delivery phases
Phase 1: foundation and setup
dygoctlbinary and operator CLI root.dygoctl setup.auth login,auth whoami,auth logout,health,version, andcapabilities.Phase 2: operator visibility
Phase 3: controlled operations
Phase 4: deployment administration
Acceptance criteria for the foundation issue
dygoctlbuilds as a separate binary from this repository.dygoctlworks without a dygo project checkout or local database configuration.dygoctl setupcollects and validates a deployment URL.auth whoamiproves the selected context and authenticated user.auth logoutrevokes the current CLI credential and removes its local copy.Non-goals for the first phase