@dharta/cli 0.6.77 → 0.6.78
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.
- package/LICENSE +1 -1
- package/README.md +215 -11
- package/dist/agent.js +3 -2
- package/dist/agent.js.map +1 -1
- package/dist/api-error.js +6 -6
- package/dist/api-error.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +860 -149
- package/dist/cli.js.map +1 -1
- package/dist/command-tree.d.ts +3 -0
- package/dist/command-tree.js +10 -0
- package/dist/command-tree.js.map +1 -0
- package/dist/commands/agents.d.ts +54 -17
- package/dist/commands/agents.js +246 -136
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/analytics.js +6 -5
- package/dist/commands/analytics.js.map +1 -1
- package/dist/commands/api.js +71 -86
- package/dist/commands/api.js.map +1 -1
- package/dist/commands/appearance.js +5 -6
- package/dist/commands/appearance.js.map +1 -1
- package/dist/commands/artifact.js +7 -6
- package/dist/commands/artifact.js.map +1 -1
- package/dist/commands/audit-log.js +2 -1
- package/dist/commands/audit-log.js.map +1 -1
- package/dist/commands/auth.js +26 -6
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/caps.js +11 -15
- package/dist/commands/caps.js.map +1 -1
- package/dist/commands/deploy.js +25 -10
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +10 -1
- package/dist/commands/dev.js +56 -25
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +60 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/embed-keys.js +4 -13
- package/dist/commands/embed-keys.js.map +1 -1
- package/dist/commands/env.js +4 -7
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/files.js +3 -4
- package/dist/commands/files.js.map +1 -1
- package/dist/commands/fleet.d.ts +129 -0
- package/dist/commands/fleet.js +408 -0
- package/dist/commands/fleet.js.map +1 -0
- package/dist/commands/genui.d.ts +2 -0
- package/dist/commands/genui.js +53 -0
- package/dist/commands/genui.js.map +1 -0
- package/dist/commands/git-credential.js +2 -3
- package/dist/commands/git-credential.js.map +1 -1
- package/dist/commands/kartas.d.ts +9 -0
- package/dist/commands/kartas.js +33 -11
- package/dist/commands/kartas.js.map +1 -1
- package/dist/commands/keys.d.ts +17 -18
- package/dist/commands/keys.js +108 -19
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/login.js +2 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/members.d.ts +10 -0
- package/dist/commands/members.js +20 -6
- package/dist/commands/members.js.map +1 -1
- package/dist/commands/model-connections.d.ts +44 -0
- package/dist/commands/model-connections.js +435 -0
- package/dist/commands/model-connections.js.map +1 -0
- package/dist/commands/open.d.ts +2 -2
- package/dist/commands/open.js +4 -3
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/org.d.ts +9 -0
- package/dist/commands/org.js +42 -0
- package/dist/commands/org.js.map +1 -0
- package/dist/commands/organization.d.ts +16 -0
- package/dist/commands/organization.js +118 -0
- package/dist/commands/organization.js.map +1 -0
- package/dist/commands/parity.js +1 -3
- package/dist/commands/parity.js.map +1 -1
- package/dist/commands/repos.d.ts +4 -0
- package/dist/commands/repos.js +17 -0
- package/dist/commands/repos.js.map +1 -0
- package/dist/commands/rollback.js +2 -3
- package/dist/commands/rollback.js.map +1 -1
- package/dist/commands/schedules.js +26 -21
- package/dist/commands/schedules.js.map +1 -1
- package/dist/commands/scopes.js +8 -1
- package/dist/commands/scopes.js.map +1 -1
- package/dist/commands/sessions.js +9 -3
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/setup.js +5 -4
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.js +24 -11
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/webhooks.d.ts +4 -1
- package/dist/commands/webhooks.js +21 -16
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/completions.js +24 -13
- package/dist/completions.js.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.js +121 -7
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +2 -0
- package/dist/context.js +23 -7
- package/dist/context.js.map +1 -1
- package/dist/docs/cli-reference.d.ts +2 -0
- package/dist/docs/cli-reference.js +191 -0
- package/dist/docs/cli-reference.js.map +1 -0
- package/dist/exit-codes.d.ts +25 -0
- package/dist/exit-codes.js +107 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/genui.d.ts +178 -0
- package/dist/genui.js +1130 -0
- package/dist/genui.js.map +1 -0
- package/dist/harnesses.js +2 -1
- package/dist/harnesses.js.map +1 -1
- package/dist/jq.d.ts +4 -0
- package/dist/jq.js +91 -0
- package/dist/jq.js.map +1 -0
- package/dist/login-offer.js +6 -2
- package/dist/login-offer.js.map +1 -1
- package/dist/manifest.d.ts +12 -0
- package/dist/manifest.js +126 -0
- package/dist/manifest.js.map +1 -1
- package/dist/model-auth.d.ts +29 -0
- package/dist/model-auth.js +117 -0
- package/dist/model-auth.js.map +1 -0
- package/dist/model-settings.d.ts +23 -0
- package/dist/model-settings.js +186 -0
- package/dist/model-settings.js.map +1 -0
- package/dist/money.js +2 -1
- package/dist/money.js.map +1 -1
- package/dist/output.d.ts +6 -0
- package/dist/output.js +54 -0
- package/dist/output.js.map +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +1 -1
- package/dist/scaffold.js +2 -1
- package/dist/scaffold.js.map +1 -1
- package/dist/validators.js +17 -11
- package/dist/validators.js.map +1 -1
- package/dist/version-check.d.ts +1 -1
- package/dist/version-check.js +1 -1
- package/dist/version-check.js.map +1 -1
- package/node_modules/@dharta/contracts/LICENSE +21 -0
- package/node_modules/@dharta/contracts/README.md +45 -0
- package/node_modules/@dharta/contracts/artifact-runtime.json +750 -0
- package/node_modules/@dharta/contracts/dist/activity.d.ts +62 -0
- package/node_modules/@dharta/contracts/dist/activity.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/activity.js +178 -0
- package/node_modules/@dharta/contracts/dist/activity.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-formats.d.ts +20 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-formats.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-formats.js +53 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-formats.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-validators.generated.d.ts +37 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-validators.generated.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-validators.generated.js +5107 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-validators.generated.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.d.ts +154 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.generated.d.ts +1670 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.generated.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.generated.js +1903 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.generated.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.js +377 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/index.d.ts +6 -0
- package/node_modules/@dharta/contracts/dist/index.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/index.js +6 -0
- package/node_modules/@dharta/contracts/dist/index.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/model-auth.d.ts +31 -0
- package/node_modules/@dharta/contracts/dist/model-auth.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/model-auth.js +45 -0
- package/node_modules/@dharta/contracts/dist/model-auth.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/tasks.d.ts +44 -0
- package/node_modules/@dharta/contracts/dist/tasks.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/tasks.js +127 -0
- package/node_modules/@dharta/contracts/dist/tasks.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/wire-events.d.ts +71 -0
- package/node_modules/@dharta/contracts/dist/wire-events.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/wire-events.js +48 -0
- package/node_modules/@dharta/contracts/dist/wire-events.js.map +1 -0
- package/node_modules/@dharta/contracts/model-auth-capabilities-v1.json +168 -0
- package/node_modules/@dharta/contracts/model-auth-reasons-v1.json +38 -0
- package/node_modules/@dharta/contracts/package.json +44 -0
- package/node_modules/@dharta/contracts/src/activity.ts +215 -0
- package/node_modules/@dharta/contracts/src/artifact-runtime-formats.ts +54 -0
- package/node_modules/@dharta/contracts/src/artifact-runtime-validators.generated.ts +29 -0
- package/node_modules/@dharta/contracts/src/artifact-runtime.generated.ts +2093 -0
- package/node_modules/@dharta/contracts/src/artifact-runtime.ts +520 -0
- package/node_modules/@dharta/contracts/src/index.ts +5 -0
- package/node_modules/@dharta/contracts/src/model-auth.ts +82 -0
- package/node_modules/@dharta/contracts/src/tasks.ts +142 -0
- package/node_modules/@dharta/contracts/src/wire-events.ts +150 -0
- package/node_modules/@dharta/contracts/wire-events.json +29 -0
- package/node_modules/@dharta/sdk/LICENSE +1 -1
- package/node_modules/@dharta/sdk/README.md +22 -8
- package/node_modules/@dharta/sdk/dist/errors.d.ts +9 -7
- package/node_modules/@dharta/sdk/dist/errors.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/errors.js +36 -18
- package/node_modules/@dharta/sdk/dist/errors.js.map +1 -1
- package/node_modules/@dharta/sdk/dist/fleet.d.ts +69 -0
- package/node_modules/@dharta/sdk/dist/fleet.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/fleet.js +240 -0
- package/node_modules/@dharta/sdk/dist/fleet.js.map +1 -0
- package/node_modules/@dharta/sdk/dist/http.d.ts +6 -2
- package/node_modules/@dharta/sdk/dist/http.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/http.js +71 -12
- package/node_modules/@dharta/sdk/dist/http.js.map +1 -1
- package/node_modules/@dharta/sdk/dist/idempotency.d.ts +12 -0
- package/node_modules/@dharta/sdk/dist/idempotency.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/idempotency.js +72 -0
- package/node_modules/@dharta/sdk/dist/idempotency.js.map +1 -0
- package/node_modules/@dharta/sdk/dist/index.d.ts +20 -6
- package/node_modules/@dharta/sdk/dist/index.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/index.js +27 -4
- package/node_modules/@dharta/sdk/dist/index.js.map +1 -1
- package/node_modules/@dharta/sdk/dist/resources.d.ts +108 -13
- package/node_modules/@dharta/sdk/dist/resources.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/resources.js +403 -57
- package/node_modules/@dharta/sdk/dist/resources.js.map +1 -1
- package/node_modules/@dharta/sdk/dist/types.d.ts +436 -16
- package/node_modules/@dharta/sdk/dist/types.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/types.js +31 -2
- package/node_modules/@dharta/sdk/dist/types.js.map +1 -1
- package/node_modules/@dharta/sdk/package.json +9 -3
- package/node_modules/@dharta/sdk/src/errors.ts +41 -18
- package/node_modules/@dharta/sdk/src/fleet.ts +339 -0
- package/node_modules/@dharta/sdk/src/http.ts +110 -17
- package/node_modules/@dharta/sdk/src/idempotency.ts +101 -0
- package/node_modules/@dharta/sdk/src/index.ts +50 -11
- package/node_modules/@dharta/sdk/src/resources.ts +549 -68
- package/node_modules/@dharta/sdk/src/types.ts +629 -20
- package/package.json +16 -6
- package/src/agent.ts +3 -2
- package/src/api-error.ts +6 -5
- package/src/cli.ts +978 -163
- package/src/command-tree.ts +13 -0
- package/src/commands/agents.ts +365 -167
- package/src/commands/analytics.ts +6 -5
- package/src/commands/api.ts +73 -92
- package/src/commands/appearance.ts +5 -6
- package/src/commands/artifact.ts +7 -6
- package/src/commands/audit-log.ts +2 -1
- package/src/commands/auth.ts +25 -5
- package/src/commands/caps.ts +11 -15
- package/src/commands/deploy.ts +18 -4
- package/src/commands/dev.ts +86 -25
- package/src/commands/doctor.ts +69 -0
- package/src/commands/embed-keys.ts +4 -14
- package/src/commands/env.ts +4 -7
- package/src/commands/files.ts +3 -4
- package/src/commands/fleet.ts +672 -0
- package/src/commands/genui.ts +59 -0
- package/src/commands/git-credential.ts +2 -3
- package/src/commands/kartas.ts +45 -11
- package/src/commands/keys.ts +152 -35
- package/src/commands/login.ts +2 -1
- package/src/commands/members.ts +31 -6
- package/src/commands/model-connections.ts +547 -0
- package/src/commands/open.ts +5 -4
- package/src/commands/org.ts +57 -0
- package/src/commands/organization.ts +153 -0
- package/src/commands/parity.ts +1 -3
- package/src/commands/repos.ts +23 -0
- package/src/commands/rollback.ts +2 -3
- package/src/commands/schedules.ts +33 -22
- package/src/commands/scopes.ts +8 -1
- package/src/commands/sessions.ts +9 -3
- package/src/commands/setup.ts +5 -4
- package/src/commands/update.ts +28 -12
- package/src/commands/webhooks.ts +30 -19
- package/src/completions.ts +25 -13
- package/src/config.ts +141 -9
- package/src/context.ts +34 -7
- package/src/docs/cli-reference.ts +206 -0
- package/src/exit-codes.ts +122 -0
- package/src/genui.ts +1398 -0
- package/src/harnesses.ts +2 -1
- package/src/jq.ts +109 -0
- package/src/login-offer.ts +6 -2
- package/src/manifest.ts +134 -0
- package/src/model-auth.ts +173 -0
- package/src/model-settings.ts +222 -0
- package/src/money.ts +5 -1
- package/src/output.ts +60 -0
- package/src/runtime.ts +1 -1
- package/src/scaffold.ts +2 -1
- package/src/validators.ts +18 -11
- package/src/version-check.ts +1 -1
- package/dist/commands/model-keys.d.ts +0 -22
- package/dist/commands/model-keys.js +0 -222
- package/dist/commands/model-keys.js.map +0 -1
- package/src/commands/model-keys.ts +0 -278
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as readline from "node:readline";
|
|
|
5
5
|
import { Argument, Command, InvalidArgumentError, Option } from "commander";
|
|
6
6
|
import { API_KEY_SCOPES } from "@dharta/sdk";
|
|
7
7
|
import { buildContext } from "./context.js";
|
|
8
|
-
import { resolveBaseUrl } from "./config.js";
|
|
8
|
+
import { requestedProfileName, resolveBaseUrl, setRequestedIdempotencyKey, setRequestedProfile, } from "./config.js";
|
|
9
9
|
import { inferAgentSlug, validateAgentSelectorOptions, validateAgentSlug } from "./agent.js";
|
|
10
10
|
import { login } from "./commands/login.js";
|
|
11
11
|
import { authLogout, authLogoutData, authStatus, authStatusData, authToken, } from "./commands/auth.js";
|
|
@@ -13,18 +13,22 @@ import { whoami, whoamiData } from "./commands/whoami.js";
|
|
|
13
13
|
import { api as apiCmd, formatApiResult, prepareApiOptions, validateApiRequest } from "./commands/api.js";
|
|
14
14
|
import { auditLog, auditLogData, validateAuditLogInput } from "./commands/audit-log.js";
|
|
15
15
|
import { COST_ANALYTICS_GROUPS, COST_ANALYTICS_RANGES, ENTITY_ANALYTICS_RANGES, analytics, analyticsData, normalizeAnalyticsOptions, } from "./commands/analytics.js";
|
|
16
|
-
import { keysCreate, keysCreateData, keysList, keysListData, keysRename, keysRenameData, keysRevoke, keysRevokeData, validateKeysCreateInput, } from "./commands/keys.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
16
|
+
import { keysBulk, keysBulkData, keysCreate, keysCreateData, keysDisable, keysDisableData, keysEnable, keysEnableData, keysList, keysListData, keysRename, keysRenameData, keysRevoke, keysRevokeData, keysRotate, keysRotateData, KEY_BULK_ACTIONS, KEY_ROTATION_GRACE_PERIODS, validateKeysBulkInput, validateKeysCreateInput, validateKeysRotateInput, } from "./commands/keys.js";
|
|
17
|
+
import { modelConnectionsConfigureModels, modelConnectionsConfigureModelsData, modelConnectionsCreate, modelConnectionsCreateData, modelConnectionsList, modelConnectionsListData, modelConnectionsModels, modelConnectionsModelsData, modelConnectionsModelsWritesOffers, modelConnectionsRevoke, modelConnectionsRevokeData, modelConnectionsRotate, modelConnectionsRotateData, prepareModelConnectionsCreateOptions, prepareModelConnectionsModelsOptions, prepareModelConnectionsRotateOptions, MODEL_API_FORMATS, validateModelConnectionReference, validateModelConnectionsCreateOptions, validateModelConnectionsModelsOptions, validateModelConnectionsRotateOptions, } from "./commands/model-connections.js";
|
|
18
|
+
import { ORG_ENDPOINT_KINDS, orgModelSet, orgModelSetData, orgModelShow, orgModelShowData, validateOrgModelSetOptions, } from "./commands/organization.js";
|
|
19
|
+
import { membersInvite, membersInviteData, membersList, membersListData, membersRemove, membersRemoveData, membersResendInvitation, membersResendInvitationData, membersRevokeInvitation, membersRevokeInvitationData, membersSetRole, membersSetRoleData, validateMembersInviteInput, } from "./commands/members.js";
|
|
20
|
+
import { orgRename, orgRenameData, orgSupportAccess, orgSupportAccessData, orgTranscriptAccess, orgTranscriptAccessData, normalizeOrganizationName, } from "./commands/org.js";
|
|
21
|
+
import { reposDisconnectGithub, reposDisconnectGithubData } from "./commands/repos.js";
|
|
22
|
+
import { kartaMembersGrant, kartaMembersGrantData, kartaMembersRevoke, kartaMembersRevokeData, kartaMembersSetRole, kartaMembersSetRoleData, kartasArchive, kartasArchiveData, kartasConfigure, kartasConfigureData, kartasRestore, kartasRestoreData, kartasCreate, kartasCreateData, kartasList, kartasListData, kartasName, kartasNameData, kartasShow, kartasShowData, kartaEnvList, kartaEnvListData, kartaEnvSet, kartaEnvSetData, kartaEnvUnset, kartaEnvUnsetData, kartaShare, kartaShareData, kartaUnshare, kartaUnshareData, validateKartaCreateOptions, validateKartaConfigureOptions, validateKartaNameOptions, } from "./commands/kartas.js";
|
|
20
23
|
import { usage as usageCmd, usageData } from "./commands/usage.js";
|
|
21
|
-
import { agentsActivateRelease, agentsActivateReleaseData, agentsDashboardEditsSet, agentsDashboardEditsSetData, agentsDelete, agentsDeleteData, agentsList, agentsListData, agentsModelSet, agentsModelSetData, agentsReleases, agentsReleasesData, agentsShow, agentsShowData, agentsServingSet, agentsServingSetData, agentsWorkspaceInspectableSet, agentsWorkspaceInspectableSetData, agentsWorkspaceAccessShow, agentsWorkspaceAccessShowData, agentsWorkspaceAccessSet, agentsWorkspaceAccessSetData, parseWorkspaceAccessAssignments, validateAgentModelSetOptions, } from "./commands/agents.js";
|
|
24
|
+
import { agentsActivateRelease, agentsActivateReleaseData, agentsCreate, agentsCreateData, agentsCreateFromTemplate, agentsCreateFromTemplateData, agentsDashboardEditsSet, agentsDashboardEditsSetData, agentsDelete, agentsDeleteData, agentsDurableWorkspaceSet, agentsDurableWorkspaceSetData, agentsGithubRepos, agentsGithubReposData, agentsList, agentsListData, agentsRedeploy, agentsRedeployData, agentsRename, agentsRenameData, agentsRetryRelease, agentsRetryReleaseData, agentsModelSet, agentsModelSetData, agentsReleases, agentsReleasesData, agentsShow, agentsShowData, agentsServingSet, agentsServingSetData, agentsWorkspaceInspectableSet, agentsWorkspaceInspectableSetData, agentsWorkspaceAccessShow, agentsWorkspaceAccessShowData, agentsWorkspaceAccessSet, agentsWorkspaceAccessSetData, parseWorkspaceAccessAssignments, validateAgentCreateFromTemplateInput, validateAgentCreateInput, validateAgentModelSetOptions, } from "./commands/agents.js";
|
|
22
25
|
import { embedKeysClearIdentity, embedKeysClearIdentityData, embedKeysCreate, embedKeysCreateData, embedKeysList, embedKeysListData, embedKeysRevoke, embedKeysRevokeData, embedKeysRotate, embedKeysRotateData, embedKeysSetIdentity, embedKeysSetIdentityData, embedKeysToggle, embedKeysToggleData, parseOrigins, validateEmbedKeysCreateInput, } from "./commands/embed-keys.js";
|
|
23
26
|
import { capsEndUser, capsEndUserData, capsEndUserSet, capsEndUserSetData, capsBudget, capsBudgetData, capsBudgetSet, capsBudgetSetData, capsInstance, capsInstanceData, capsInstanceSet, capsInstanceSetData, capsSeat, capsSeatData, capsSeatSet, capsSeatSetData, validateBudgetSetOptions, validateCapSetOptions, } from "./commands/caps.js";
|
|
24
27
|
import { appearanceGet, appearanceGetData, appearanceSet, appearanceSetData, validateAppearanceSetInput, } from "./commands/appearance.js";
|
|
25
28
|
import { schedulesAction, schedulesActionData, schedulesCreate, schedulesCreateData, schedulesDelete, schedulesDeleteData, schedulesList, schedulesListData, validateSchedulesCreateInput, } from "./commands/schedules.js";
|
|
26
29
|
import { directoryEndUsers, directoryEndUsersData, directoryInstances, directoryInstancesData, directorySessions, directorySessionsData, validateDirectoryOptions, } from "./commands/directories.js";
|
|
27
|
-
import {
|
|
30
|
+
import { FLEET_ENTITY_TYPES, FLEET_SELECTION_MODES, FLEET_SNOOZE_DURATIONS, FLEET_VIEW_VISIBILITIES, fleetAnalyticsSave, fleetAnalyticsSaveData, fleetAnalyticsUnpin, fleetAnalyticsUnpinData, fleetExportCreate, fleetExportCreateData, fleetFinding, fleetFindingAssign, fleetFindingAssignData, fleetFindingClassify, fleetFindingClassifyData, fleetFindingData, fleetFindingSnooze, fleetFindingSnoozeData, fleetFindingUpdate, fleetFindingUpdateData, fleetOperationCancel, fleetOperationCancelData, fleetOperationConfirm, fleetOperationConfirmData, fleetOperationCreate, fleetOperationCreateData, fleetOperationRetry, fleetOperationRetryData, fleetRollout, fleetRolloutData, fleetRolloutRollback, fleetRolloutRollbackData, fleetViewCreate, fleetViewCreateData, fleetViewDelete, fleetViewDeleteData, fleetViewFavorite, fleetViewFavoriteData, fleetViewUnfavorite, fleetViewUnfavoriteData, fleetViewUpdate, fleetViewUpdateData, } from "./commands/fleet.js";
|
|
31
|
+
import { parseEvents, webhooksCreate, webhooksCreateData, webhooksDelete, webhooksDeleteData, webhooksEnable, webhooksEnableData, webhooksList, webhooksListData, webhooksTest, webhooksTestData, webhooksUpdate, webhooksUpdateData, validateWebhooksCreateInput, validateWebhooksUpdateInput, } from "./commands/webhooks.js";
|
|
28
32
|
import { rollback, rollbackData } from "./commands/rollback.js";
|
|
29
33
|
import { deploy, inferMode, validateDeployDir } from "./commands/deploy.js";
|
|
30
34
|
import { status, statusData } from "./commands/status.js";
|
|
@@ -36,6 +40,8 @@ import { offerLogin } from "./login-offer.js";
|
|
|
36
40
|
import { doctor } from "./commands/doctor.js";
|
|
37
41
|
import { dev as devCmd } from "./commands/dev.js";
|
|
38
42
|
import { registerArtifactCommands } from "./commands/artifact.js";
|
|
43
|
+
import { registerGenuiCommands } from "./commands/genui.js";
|
|
44
|
+
import { flushJsonPayload, isJson, printJson, resetJsonPayload } from "./output.js";
|
|
39
45
|
import { isHandoffTarget, open as openCmd, openData, openHandoff, openHandoffData, OPEN_TARGETS_HELP, normalizeOpenTarget, validateOpenTarget, } from "./commands/open.js";
|
|
40
46
|
import { envDiff, envDiffData, envList, envListData, envPull, envPullData, envSet, envSetData, envUnset, envUnsetData, validateEnvAssignment, validateEnvDiffOptions, validateEnvName, validateEnvPullOptions, } from "./commands/env.js";
|
|
41
47
|
import { ps as psCmd, psData, run as runCmd, sessionsList, sessionsListData, sessionsShow, sessionsShowData, validateSessionsListOptions, } from "./commands/sessions.js";
|
|
@@ -43,35 +49,16 @@ import { update } from "./commands/update.js";
|
|
|
43
49
|
import { filesLs, filesLsData, filesGet } from "./commands/files.js";
|
|
44
50
|
import { gitCredential } from "./commands/git-credential.js";
|
|
45
51
|
import { bashCompletion, zshCompletion } from "./completions.js";
|
|
52
|
+
import { visibleSubcommands } from "./command-tree.js";
|
|
53
|
+
import { CliUsageError, exitCodeForError, isCommanderError, isNotAuthenticatedError } from "./exit-codes.js";
|
|
54
|
+
import { armJqFilter } from "./jq.js";
|
|
46
55
|
import { closestChoice, normalizeHttpUrl, normalizeNonBlank, parsePositiveInteger, parseReleaseVersion } from "./validators.js";
|
|
56
|
+
import { DEV_MODEL_AUTH_VALUES, MODEL_CONNECTION_PROVIDERS } from "./model-auth.js";
|
|
47
57
|
const MEMBER_ROLES = ["owner", "admin", "developer", "billing", "viewer"];
|
|
48
58
|
const DHARTA_ACCESS_AUDIENCES = ["members", "anonymous", "off"];
|
|
49
59
|
const DHARTA_MEMBER_ROLES = ["viewer", "participant", "manager"];
|
|
50
|
-
const MODEL_KEY_AUTH_TYPES = ["api_key", "oauth_subscription"];
|
|
51
|
-
const AGENT_MODEL_SOURCES = ["inherit", "platform"];
|
|
52
60
|
const CLI_API_KEY_SCOPES = API_KEY_SCOPES;
|
|
53
61
|
const STATE_HELP = "State values: on/off, enabled/disabled, true/false.";
|
|
54
|
-
// --json output (RFC 0013 §3): every command that produces a result
|
|
55
|
-
// payload prints it as JSON when --json is set. Progress narration
|
|
56
|
-
// (device-flow codes, download logs) moves to stderr so stdout stays
|
|
57
|
-
// parseable. Commands whose stdout is a stream, a REPL, a script, or a
|
|
58
|
-
// protocol rather than a result payload (dev, logs, completion,
|
|
59
|
-
// git-credential, and `deploy --mode git` whose output is the live
|
|
60
|
-
// push sideband) reject --json. `deploy --mode folder` returns a
|
|
61
|
-
// single payload, so it supports --json.
|
|
62
|
-
//
|
|
63
|
-
// Mechanics: the flag is registered on every node of the command tree
|
|
64
|
-
// so commander's
|
|
65
|
-
// outermost option scan consumes it wherever it appears on the line -
|
|
66
|
-
// so actions read it through optsWithGlobals() on their Command. Commands
|
|
67
|
-
// that always reject JSON keep a hidden parser option so help/completions
|
|
68
|
-
// do not advertise an invalid mode.
|
|
69
|
-
function isJson(cmd) {
|
|
70
|
-
return Boolean(cmd.optsWithGlobals().json);
|
|
71
|
-
}
|
|
72
|
-
function printJson(payload) {
|
|
73
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
74
|
-
}
|
|
75
62
|
function commandOpts(cmd) {
|
|
76
63
|
return cmd.optsWithGlobals();
|
|
77
64
|
}
|
|
@@ -80,7 +67,7 @@ function validatePositionalAgentSelector(slug, opts) {
|
|
|
80
67
|
return;
|
|
81
68
|
validateAgentSlug(slug, "agent slug");
|
|
82
69
|
if (opts.agent !== undefined || opts.project !== undefined) {
|
|
83
|
-
throw new
|
|
70
|
+
throw new CliUsageError("Use either the positional agent slug or --agent/--project, not both.");
|
|
84
71
|
}
|
|
85
72
|
}
|
|
86
73
|
function validateCreateInput(pathArg, opts) {
|
|
@@ -104,9 +91,69 @@ async function resolveAgentOptions(opts, positionalSlug) {
|
|
|
104
91
|
return { ...opts, agent, project: undefined };
|
|
105
92
|
}
|
|
106
93
|
function rejectJson(cmd, name) {
|
|
107
|
-
if (isJson(cmd))
|
|
108
|
-
|
|
109
|
-
|
|
94
|
+
if (!isJson(cmd))
|
|
95
|
+
return;
|
|
96
|
+
// --jq is rejected wherever --json is, and for the same reason: there is no
|
|
97
|
+
// payload to filter. Name the flag the user actually passed.
|
|
98
|
+
const flag = cmd.optsWithGlobals().jq !== undefined ? "--jq" : "--json";
|
|
99
|
+
throw new CliUsageError(`${flag} is not supported for \`${name}\` - its output is not a single payload. Run it without ${flag}.`);
|
|
100
|
+
}
|
|
101
|
+
// A command group prints help and issues no request, so an Idempotency-Key on
|
|
102
|
+
// one is a mistake with nowhere to land. Read-only LEAF commands are not
|
|
103
|
+
// rejected: see the P9 entry in the RFC 0048 implementation log for why.
|
|
104
|
+
function rejectIdempotencyKey(cmd, name) {
|
|
105
|
+
if (cmd.optsWithGlobals().idempotencyKey === undefined)
|
|
106
|
+
return;
|
|
107
|
+
throw new CliUsageError(`--idempotency-key is not supported for \`${name}\` - it prints help and sends no request. ` +
|
|
108
|
+
"Put it on the command that performs the mutation.");
|
|
109
|
+
}
|
|
110
|
+
// `--idempotency-key` names an `Idempotency-Key` for a write to the Dharta API.
|
|
111
|
+
// These commands perform no mutation the key could protect, so accepting one
|
|
112
|
+
// would silently ignore it, which is precisely the outcome a caller reaching for
|
|
113
|
+
// the flag is trying to avoid.
|
|
114
|
+
//
|
|
115
|
+
// Several of them DO talk to Dharta, and the message must not claim otherwise:
|
|
116
|
+
//
|
|
117
|
+
// - `login` runs before a credential exists. Its device-flow POSTs carry no
|
|
118
|
+
// key and the server installs no idempotency filter on them, and it then
|
|
119
|
+
// reads `/me` to learn who the new key belongs to. Reads and unprotected
|
|
120
|
+
// POSTs, no mutation.
|
|
121
|
+
// - `create` fetches `/agent_templates` and writes the result to disk.
|
|
122
|
+
// - `setup` writes files, and with `--login` it runs the login flow above.
|
|
123
|
+
// - `auth token` and `auth logout` read and rewrite the local profile.
|
|
124
|
+
// - `genui` builds a bundle, `artifact` spawns a local helper.
|
|
125
|
+
// - `doctor` and `update` talk to the package registry, never to Dharta.
|
|
126
|
+
// - `completion` prints a shell script.
|
|
127
|
+
//
|
|
128
|
+
// Read-only Dharta commands (`ps`, `usage`, `webhooks list`) perform no mutation
|
|
129
|
+
// either and are deliberately NOT refused. They are steps in a run that writes,
|
|
130
|
+
// the header rides along and is ignored server-side, and a script that sets one
|
|
131
|
+
// flag for a whole pipeline should not have to special-case them. The commands
|
|
132
|
+
// below are not that: a caller who puts the key on `dharta login` is expressing
|
|
133
|
+
// an intent it can never honour, so saying so beats accepting it.
|
|
134
|
+
const NON_MUTATING_COMMAND_PATHS = [
|
|
135
|
+
"dharta login",
|
|
136
|
+
"dharta auth token",
|
|
137
|
+
"dharta auth logout",
|
|
138
|
+
"dharta create",
|
|
139
|
+
"dharta setup",
|
|
140
|
+
"dharta genui",
|
|
141
|
+
"dharta artifact",
|
|
142
|
+
"dharta doctor",
|
|
143
|
+
"dharta update",
|
|
144
|
+
"dharta completion",
|
|
145
|
+
];
|
|
146
|
+
export function isNonMutatingCommandPath(path) {
|
|
147
|
+
return NON_MUTATING_COMMAND_PATHS.some((entry) => path === entry || path.startsWith(`${entry} `));
|
|
148
|
+
}
|
|
149
|
+
function rejectNonMutatingIdempotencyKey(cmd, key) {
|
|
150
|
+
if (key === undefined)
|
|
151
|
+
return;
|
|
152
|
+
const path = commandPath(cmd);
|
|
153
|
+
if (!isNonMutatingCommandPath(path))
|
|
154
|
+
return;
|
|
155
|
+
throw new CliUsageError(`--idempotency-key is not supported for \`${path}\` - it performs no mutation the key could protect. ` +
|
|
156
|
+
"The flag applies to commands that write to the Dharta API.");
|
|
110
157
|
}
|
|
111
158
|
function helpOnlyAction(name) {
|
|
112
159
|
return (...args) => {
|
|
@@ -121,6 +168,7 @@ function helpOnlyAction(name) {
|
|
|
121
168
|
(suggestion ? ` Did you mean \`${suggestion}\`?` : ""));
|
|
122
169
|
}
|
|
123
170
|
rejectJson(cmd, name);
|
|
171
|
+
rejectIdempotencyKey(cmd, name);
|
|
124
172
|
cmd.outputHelp();
|
|
125
173
|
};
|
|
126
174
|
}
|
|
@@ -138,23 +186,12 @@ function closestCommand(input, commands) {
|
|
|
138
186
|
return closestChoice(input, commands);
|
|
139
187
|
}
|
|
140
188
|
function commandSuggestionTokens(cmd) {
|
|
141
|
-
return Array.from(new Set(cmd.
|
|
142
|
-
.filter((child) => !child._hidden)
|
|
143
|
-
.flatMap((child) => [child.name(), ...child.aliases()])));
|
|
189
|
+
return Array.from(new Set(visibleSubcommands(cmd).flatMap((child) => [child.name(), ...child.aliases()])));
|
|
144
190
|
}
|
|
145
191
|
export function buildProgram() {
|
|
146
192
|
const program = new Command();
|
|
147
|
-
// Commander 12 has no native help groups, so render the top-level command
|
|
148
|
-
// list grouped (addHelpText below) and suppress commander's default flat
|
|
149
|
-
// list on the ROOT only - subcommand help (e.g. `dharta agent --help`) keeps
|
|
150
|
-
// commander's default rendering. `defaultHelp` is captured before the
|
|
151
|
-
// override so it supplies the unmodified list for subcommands.
|
|
152
|
-
const defaultHelp = program.createHelp();
|
|
153
193
|
program
|
|
154
194
|
.name("dharta")
|
|
155
|
-
.configureHelp({
|
|
156
|
-
visibleCommands: (cmd) => (cmd.parent === null ? [] : defaultHelp.visibleCommands(cmd)),
|
|
157
|
-
})
|
|
158
195
|
.description("Build, run, and deploy AI agents on dharta.ai - one tool from create to open.\n" +
|
|
159
196
|
"Agents are harness-native folders (Claude Code, OpenCode, DeepAgents, Goose, Codex CLI) plus dharta.toml; `dharta deploy` ships one selected folder.")
|
|
160
197
|
// Read from package.json so `--version` can never drift from the published
|
|
@@ -163,51 +200,8 @@ export function buildProgram() {
|
|
|
163
200
|
.version)
|
|
164
201
|
.addHelpText("after", [
|
|
165
202
|
"",
|
|
166
|
-
"Agent lifecycle",
|
|
167
|
-
" create Scaffold a brand-new agent",
|
|
168
|
-
" setup Configure an agent here; write dharta.toml",
|
|
169
|
-
" dev Preview locally as a user would (hot reload)",
|
|
170
|
-
" deploy Deploy this agent folder",
|
|
171
|
-
" open Open the live hosted page",
|
|
172
|
-
" status Every agent here and its live release",
|
|
173
|
-
"",
|
|
174
|
-
"Operate",
|
|
175
|
-
" sessions Inspect an agent's sessions",
|
|
176
|
-
" session View one session transcript",
|
|
177
|
-
" ps Sessions active right now",
|
|
178
|
-
" logs Stream runtime logs",
|
|
179
|
-
" files Read a karta's workspace files",
|
|
180
|
-
" send One-shot message to a deployed agent",
|
|
181
|
-
" rollback Roll back to a previous release",
|
|
182
|
-
" env Environment bindings",
|
|
183
|
-
"",
|
|
184
|
-
"Manage",
|
|
185
|
-
" agent List and show your agents",
|
|
186
|
-
" artifact Designate durable workspace work product",
|
|
187
|
-
"",
|
|
188
|
-
"Account",
|
|
189
|
-
" login Sign in (device flow)",
|
|
190
|
-
" whoami Show the authenticated principal",
|
|
191
|
-
" auth Status, tokens, logout",
|
|
192
|
-
" audit-log Export audit events",
|
|
193
|
-
" analytics Usage and cost analytics",
|
|
194
|
-
" keys API keys",
|
|
195
|
-
" model-keys BYOK provider credentials",
|
|
196
|
-
" members Organization members and invitations",
|
|
197
|
-
" kartas Durable Dharta identity, URLs, and ACLs",
|
|
198
|
-
" api Authenticated public API passthrough",
|
|
199
|
-
" embed-keys Publishable widget keys",
|
|
200
|
-
" caps Spend caps and monthly budget",
|
|
201
|
-
" appearance Agent appearance theme",
|
|
202
|
-
" schedules Recurring agent runs",
|
|
203
|
-
" directories Agent-scoped kartas, users, sessions",
|
|
204
|
-
" webhooks Event delivery endpoints",
|
|
205
|
-
"",
|
|
206
|
-
"Utilities",
|
|
207
|
-
" usage · doctor · update · completion",
|
|
208
|
-
"",
|
|
209
203
|
"Golden path: dharta login -> create -> setup -> dev -> deploy -> open",
|
|
210
|
-
"Run `
|
|
204
|
+
"Run `dharta <command> --help` for details. Docs: https://docs.dharta.ai",
|
|
211
205
|
].join("\n"))
|
|
212
206
|
.action(helpOnlyAction("dharta"));
|
|
213
207
|
program
|
|
@@ -216,19 +210,17 @@ export function buildProgram() {
|
|
|
216
210
|
.option("--with-token", "Read an API key from stdin instead (CI, air-gapped)")
|
|
217
211
|
.option("--base-url <url>", "Override the API base URL")
|
|
218
212
|
.option("--git-base-url <url>", "Override the git server base URL")
|
|
219
|
-
.option("--profile <name>", "Named profile (default: default)")
|
|
220
213
|
.action(async (opts, cmd) => {
|
|
221
214
|
if (opts.baseUrl !== undefined)
|
|
222
215
|
normalizeHttpUrl(opts.baseUrl, "--base-url");
|
|
223
216
|
if (opts.gitBaseUrl !== undefined)
|
|
224
217
|
normalizeHttpUrl(opts.gitBaseUrl, "--git-base-url");
|
|
225
|
-
if (opts.profile !== undefined)
|
|
226
|
-
normalizeNonBlank(opts.profile, "--profile");
|
|
227
218
|
const json = isJson(cmd);
|
|
228
219
|
const result = await login({
|
|
229
220
|
baseUrl: opts.baseUrl,
|
|
230
221
|
gitBaseUrl: opts.gitBaseUrl,
|
|
231
|
-
profile
|
|
222
|
+
// The global --profile names the profile this login writes.
|
|
223
|
+
profile: requestedProfileName(),
|
|
232
224
|
apiKey: opts.withToken ? await readStdin() : undefined,
|
|
233
225
|
// In JSON mode the device-flow narration (code, approve URL)
|
|
234
226
|
// still has to reach the human - on stderr.
|
|
@@ -269,13 +261,14 @@ export function buildProgram() {
|
|
|
269
261
|
});
|
|
270
262
|
auth
|
|
271
263
|
.command("logout")
|
|
272
|
-
.description("Remove the stored credential (the key stays revocable on the dashboard).")
|
|
273
|
-
.
|
|
274
|
-
|
|
264
|
+
.description("Remove the stored credential (the key stays revocable on the dashboard). Removes the default profile unless --profile names another.")
|
|
265
|
+
.action(async (_opts, cmd) => {
|
|
266
|
+
// The global --profile names the profile this removes.
|
|
267
|
+
const profile = requestedProfileName();
|
|
275
268
|
if (isJson(cmd))
|
|
276
|
-
printJson(await authLogoutData(
|
|
269
|
+
printJson(await authLogoutData(profile));
|
|
277
270
|
else
|
|
278
|
-
console.log(await authLogout(
|
|
271
|
+
console.log(await authLogout(profile));
|
|
279
272
|
});
|
|
280
273
|
program
|
|
281
274
|
.command("create [path]")
|
|
@@ -311,7 +304,7 @@ export function buildProgram() {
|
|
|
311
304
|
.action(async (pathArg, opts, cmd) => {
|
|
312
305
|
const json = isJson(cmd);
|
|
313
306
|
if (json && opts.login) {
|
|
314
|
-
throw new
|
|
307
|
+
throw new CliUsageError("--login is not supported with `dharta setup --json`. Run `dharta setup --json` first, then `dharta login`.");
|
|
315
308
|
}
|
|
316
309
|
const interactive = !json && !opts.yes && process.stdin.isTTY;
|
|
317
310
|
const rl = interactive
|
|
@@ -369,7 +362,7 @@ export function buildProgram() {
|
|
|
369
362
|
.action(async (opts, cmd) => {
|
|
370
363
|
validateAuditLogInput(opts);
|
|
371
364
|
if (opts.csv && isJson(cmd)) {
|
|
372
|
-
throw new
|
|
365
|
+
throw new CliUsageError("Use either --csv or --json for audit-log, not both.");
|
|
373
366
|
}
|
|
374
367
|
const ctx = await buildContext();
|
|
375
368
|
if (isJson(cmd))
|
|
@@ -415,7 +408,8 @@ export function buildProgram() {
|
|
|
415
408
|
});
|
|
416
409
|
program
|
|
417
410
|
.command("api [method] [path]")
|
|
418
|
-
.description("Call
|
|
411
|
+
.description("Call any public JSON API endpoint with the active profile. Unstable escape hatch: the curated commands are the stable contract, and this passthrough follows the API. " +
|
|
412
|
+
"Reachable paths start with /api/, /me, /version, /api_keys, /model_connections, or /agent_templates; what the request may do is decided server-side by the key's scopes.")
|
|
419
413
|
.option("-F, --field <key=value>", "Add a JSON-coerced field to the request body", collect, [])
|
|
420
414
|
.option("-f, --raw-field <key=value>", "Add a string field to the request body", collect, [])
|
|
421
415
|
.option("-H, --header <name:value>", "Add a safe request header", collect, [])
|
|
@@ -482,46 +476,210 @@ export function buildProgram() {
|
|
|
482
476
|
else
|
|
483
477
|
console.log(await keysRevoke(ctx, id));
|
|
484
478
|
});
|
|
485
|
-
|
|
486
|
-
|
|
479
|
+
keys
|
|
480
|
+
.command("rotate <id>")
|
|
481
|
+
.description("Replace a key with a new one carrying the same scopes, then retire the original.")
|
|
482
|
+
.addOption(choiceOption("--grace-period <window>", "How long the rotated key keeps working (default 24h)", KEY_ROTATION_GRACE_PERIODS))
|
|
483
|
+
.action(async (id, opts, cmd) => {
|
|
484
|
+
validateKeysRotateInput(id, opts);
|
|
485
|
+
const ctx = await buildContext();
|
|
486
|
+
if (isJson(cmd))
|
|
487
|
+
printJson(await keysRotateData(ctx, id, opts));
|
|
488
|
+
else
|
|
489
|
+
console.log(await keysRotate(ctx, id, opts));
|
|
490
|
+
});
|
|
491
|
+
keys
|
|
492
|
+
.command("disable <id>")
|
|
493
|
+
.description("Suspend an API key without revoking it.")
|
|
494
|
+
.action(async (id, _opts, cmd) => {
|
|
495
|
+
normalizeNonBlank(id, "API key id");
|
|
496
|
+
const ctx = await buildContext();
|
|
497
|
+
if (isJson(cmd))
|
|
498
|
+
printJson(await keysDisableData(ctx, id));
|
|
499
|
+
else
|
|
500
|
+
console.log(await keysDisable(ctx, id));
|
|
501
|
+
});
|
|
502
|
+
keys
|
|
503
|
+
.command("enable <id>")
|
|
504
|
+
.description("Return a disabled API key to service.")
|
|
505
|
+
.action(async (id, _opts, cmd) => {
|
|
506
|
+
normalizeNonBlank(id, "API key id");
|
|
507
|
+
const ctx = await buildContext();
|
|
508
|
+
if (isJson(cmd))
|
|
509
|
+
printJson(await keysEnableData(ctx, id));
|
|
510
|
+
else
|
|
511
|
+
console.log(await keysEnable(ctx, id));
|
|
512
|
+
});
|
|
513
|
+
keys
|
|
514
|
+
.command("bulk")
|
|
515
|
+
.description("Apply one state change to several API keys atomically.")
|
|
516
|
+
.addArgument(choiceArgument("<action>", "state change to apply", KEY_BULK_ACTIONS))
|
|
517
|
+
.argument("<id...>", "API key ids")
|
|
518
|
+
.action(async (action, ids, _opts, cmd) => {
|
|
519
|
+
validateKeysBulkInput(action, ids);
|
|
520
|
+
const ctx = await buildContext();
|
|
521
|
+
if (isJson(cmd))
|
|
522
|
+
printJson(await keysBulkData(ctx, action, ids));
|
|
523
|
+
else
|
|
524
|
+
console.log(await keysBulk(ctx, action, ids));
|
|
525
|
+
});
|
|
526
|
+
const models = program
|
|
527
|
+
.command("models")
|
|
528
|
+
.description("Manage model configuration and authentication.")
|
|
529
|
+
.action(helpOnlyAction("dharta models"));
|
|
530
|
+
const modelConnections = models
|
|
531
|
+
.command("auth")
|
|
532
|
+
.description("Manage model provider connections.")
|
|
533
|
+
.action(helpOnlyAction("dharta models auth"));
|
|
534
|
+
modelConnections
|
|
487
535
|
.command("list")
|
|
488
536
|
.description("List model provider credentials.")
|
|
489
537
|
.action(async (_opts, cmd) => {
|
|
490
538
|
const ctx = await buildContext();
|
|
491
539
|
if (isJson(cmd))
|
|
492
|
-
printJson(await
|
|
540
|
+
printJson(await modelConnectionsListData(ctx));
|
|
493
541
|
else
|
|
494
|
-
console.log(await
|
|
542
|
+
console.log(await modelConnectionsList(ctx));
|
|
495
543
|
});
|
|
496
|
-
|
|
544
|
+
modelConnections
|
|
497
545
|
.command("create")
|
|
498
546
|
.description("Store an encrypted model provider credential.")
|
|
499
|
-
.addArgument(choiceArgument("<provider>", "provider",
|
|
547
|
+
.addArgument(choiceArgument("<provider>", "provider", MODEL_CONNECTION_PROVIDERS))
|
|
500
548
|
.argument("<name>", "connector name")
|
|
501
549
|
.option("--key <plaintext>", "Provider API key plaintext")
|
|
502
550
|
.option("--key-stdin", "Read provider API key plaintext from stdin")
|
|
503
|
-
.
|
|
551
|
+
.option("--slug <slug>", "Connector slug used by --connector and model references (default: derived from the name)")
|
|
504
552
|
.option("--endpoint-url <url>", "Provider endpoint URL override")
|
|
505
553
|
.addOption(choiceOption("--api-format <format>", "Explicit provider API format", MODEL_API_FORMATS))
|
|
506
554
|
.action(async (provider, name, opts, cmd) => {
|
|
507
|
-
|
|
508
|
-
const preparedOpts = await
|
|
555
|
+
validateModelConnectionsCreateOptions(provider, name, opts);
|
|
556
|
+
const preparedOpts = await prepareModelConnectionsCreateOptions(provider, name, opts);
|
|
509
557
|
const ctx = await buildContext();
|
|
510
558
|
if (isJson(cmd))
|
|
511
|
-
printJson(await
|
|
559
|
+
printJson(await modelConnectionsCreateData(ctx, provider, name, preparedOpts));
|
|
512
560
|
else
|
|
513
|
-
console.log(await
|
|
561
|
+
console.log(await modelConnectionsCreate(ctx, provider, name, preparedOpts));
|
|
514
562
|
});
|
|
515
|
-
|
|
516
|
-
.command("
|
|
563
|
+
modelConnections
|
|
564
|
+
.command("rotate <id|slug>")
|
|
565
|
+
.description("Replace a connector's stored credential, keeping its slug and every selection that names it.")
|
|
566
|
+
.option("--key <plaintext>", "New provider API key plaintext")
|
|
567
|
+
.option("--key-stdin", "Read the new provider API key plaintext from stdin")
|
|
568
|
+
.option("--name <name>", "Rename the connector while rotating it")
|
|
569
|
+
.action(async (reference, opts, cmd) => {
|
|
570
|
+
validateModelConnectionsRotateOptions(reference, opts);
|
|
571
|
+
const preparedOpts = await prepareModelConnectionsRotateOptions(reference, opts);
|
|
572
|
+
const ctx = await buildContext();
|
|
573
|
+
if (isJson(cmd))
|
|
574
|
+
printJson(await modelConnectionsRotateData(ctx, reference, preparedOpts));
|
|
575
|
+
else
|
|
576
|
+
console.log(await modelConnectionsRotate(ctx, reference, preparedOpts));
|
|
577
|
+
});
|
|
578
|
+
modelConnections
|
|
579
|
+
.command("models <id|slug>")
|
|
580
|
+
.description("Show the models a connector serves, or replace its enabled set and default.")
|
|
581
|
+
.option("--enable <models>", "Comma-separated model ids to enable; this replaces the whole enabled set")
|
|
582
|
+
.option("--enable-stdin", "Read the model ids to enable from stdin")
|
|
583
|
+
.option("--default <model>", "Connector default model; must be in the enabled set")
|
|
584
|
+
.option("--clear-default", "Leave the connector with no default model")
|
|
585
|
+
.action(async (reference, opts, cmd) => {
|
|
586
|
+
validateModelConnectionsModelsOptions(reference, opts);
|
|
587
|
+
if (!modelConnectionsModelsWritesOffers(opts)) {
|
|
588
|
+
validateModelConnectionReference(reference);
|
|
589
|
+
const readCtx = await buildContext();
|
|
590
|
+
if (isJson(cmd))
|
|
591
|
+
printJson(await modelConnectionsModelsData(readCtx, reference));
|
|
592
|
+
else
|
|
593
|
+
console.log(await modelConnectionsModels(readCtx, reference));
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
const preparedOpts = await prepareModelConnectionsModelsOptions(reference, opts);
|
|
597
|
+
const ctx = await buildContext();
|
|
598
|
+
if (isJson(cmd))
|
|
599
|
+
printJson(await modelConnectionsConfigureModelsData(ctx, reference, preparedOpts));
|
|
600
|
+
else
|
|
601
|
+
console.log(await modelConnectionsConfigureModels(ctx, reference, preparedOpts));
|
|
602
|
+
});
|
|
603
|
+
modelConnections
|
|
604
|
+
.command("revoke <id|slug>")
|
|
517
605
|
.description("Revoke a model provider credential.")
|
|
518
|
-
.action(async (
|
|
519
|
-
|
|
606
|
+
.action(async (reference, _opts, cmd) => {
|
|
607
|
+
validateModelConnectionReference(reference);
|
|
608
|
+
const ctx = await buildContext();
|
|
609
|
+
if (isJson(cmd))
|
|
610
|
+
printJson(await modelConnectionsRevokeData(ctx, reference));
|
|
611
|
+
else
|
|
612
|
+
console.log(await modelConnectionsRevoke(ctx, reference));
|
|
613
|
+
});
|
|
614
|
+
const org = program
|
|
615
|
+
.command("org")
|
|
616
|
+
.description("Manage organization settings.")
|
|
617
|
+
.action(helpOnlyAction("dharta org"));
|
|
618
|
+
const orgModel = org
|
|
619
|
+
.command("model")
|
|
620
|
+
.description("Show the organization connector order, model reference, parameters, and what they resolve to.")
|
|
621
|
+
.action(async (_opts, cmd) => {
|
|
622
|
+
const ctx = await buildContext();
|
|
623
|
+
if (isJson(cmd))
|
|
624
|
+
printJson(await orgModelShowData(ctx));
|
|
625
|
+
else
|
|
626
|
+
console.log(await orgModelShow(ctx));
|
|
627
|
+
});
|
|
628
|
+
orgModel
|
|
629
|
+
.command("set")
|
|
630
|
+
.description("Update the organization connector order, model reference, endpoint override, and portable model parameters.")
|
|
631
|
+
.option("--connector <slugs>", "Ordered connector slugs from `dharta models auth list`, or an empty string to unset")
|
|
632
|
+
.option("--model-ref <reference>", "Model reference: <model>, connector:<slug>/<model>, or an empty string to unset")
|
|
633
|
+
.option("--endpoint-url <url>", "Public HTTPS endpoint to call instead of the provider's standard API, or an empty string to clear")
|
|
634
|
+
.addOption(choiceOption("--endpoint-kind <kind>", "Wire protocol for --endpoint-url", ORG_ENDPOINT_KINDS))
|
|
635
|
+
.option("--temperature <number>", "Sampling temperature from 0 to 2")
|
|
636
|
+
.option("--clear-temperature", "Clear the organization temperature")
|
|
637
|
+
.option("--top-p <number>", "Nucleus sampling probability above 0 and at most 1")
|
|
638
|
+
.option("--clear-top-p", "Clear the organization top-p")
|
|
639
|
+
.option("--max-output-tokens <number>", "Positive output token limit")
|
|
640
|
+
.option("--clear-max-output-tokens", "Clear the organization output token limit")
|
|
641
|
+
.addOption(choiceOption("--reasoning-effort <level>", "Reasoning effort", ["low", "medium", "high"]))
|
|
642
|
+
.option("--clear-reasoning-effort", "Clear the organization reasoning effort")
|
|
643
|
+
.action(async (opts, cmd) => {
|
|
644
|
+
validateOrgModelSetOptions(opts);
|
|
520
645
|
const ctx = await buildContext();
|
|
521
646
|
if (isJson(cmd))
|
|
522
|
-
printJson(await
|
|
647
|
+
printJson(await orgModelSetData(ctx, opts));
|
|
523
648
|
else
|
|
524
|
-
console.log(await
|
|
649
|
+
console.log(await orgModelSet(ctx, opts));
|
|
650
|
+
});
|
|
651
|
+
org
|
|
652
|
+
.command("rename <name>")
|
|
653
|
+
.description("Change the organization display name. The slug never changes.")
|
|
654
|
+
.action(async (name, _opts, cmd) => {
|
|
655
|
+
normalizeOrganizationName(name);
|
|
656
|
+
const ctx = await buildContext();
|
|
657
|
+
if (isJson(cmd))
|
|
658
|
+
printJson(await orgRenameData(ctx, name));
|
|
659
|
+
else
|
|
660
|
+
console.log(await orgRename(ctx, name));
|
|
661
|
+
});
|
|
662
|
+
org
|
|
663
|
+
.command("support-access <state>")
|
|
664
|
+
.description(`Allow or block Dharta support access to session content. ${STATE_HELP}`)
|
|
665
|
+
.action(async (state, _opts, cmd) => {
|
|
666
|
+
const allowed = parseOnOff(state, "state");
|
|
667
|
+
const ctx = await buildContext();
|
|
668
|
+
if (isJson(cmd))
|
|
669
|
+
printJson(await orgSupportAccessData(ctx, allowed));
|
|
670
|
+
else
|
|
671
|
+
console.log(await orgSupportAccess(ctx, allowed));
|
|
672
|
+
});
|
|
673
|
+
org
|
|
674
|
+
.command("transcript-access <state>")
|
|
675
|
+
.description(`Allow or block API keys from reading end-user transcripts. ${STATE_HELP}`)
|
|
676
|
+
.action(async (state, _opts, cmd) => {
|
|
677
|
+
const enabled = parseOnOff(state, "state");
|
|
678
|
+
const ctx = await buildContext();
|
|
679
|
+
if (isJson(cmd))
|
|
680
|
+
printJson(await orgTranscriptAccessData(ctx, enabled));
|
|
681
|
+
else
|
|
682
|
+
console.log(await orgTranscriptAccess(ctx, enabled));
|
|
525
683
|
});
|
|
526
684
|
const members = program.command("members").description("Manage organization members.").action(helpOnlyAction("dharta members"));
|
|
527
685
|
members
|
|
@@ -540,7 +698,7 @@ export function buildProgram() {
|
|
|
540
698
|
.addOption(choiceOption("--role <role>", "owner, admin, developer, billing, or viewer", MEMBER_ROLES))
|
|
541
699
|
.action(async (email, opts, cmd) => {
|
|
542
700
|
if (opts.role === undefined) {
|
|
543
|
-
throw new
|
|
701
|
+
throw new CliUsageError("--role is required. Usage: dharta members invite <email> --role <role>");
|
|
544
702
|
}
|
|
545
703
|
validateMembersInviteInput(email);
|
|
546
704
|
const ctx = await buildContext();
|
|
@@ -555,7 +713,7 @@ export function buildProgram() {
|
|
|
555
713
|
.addOption(choiceOption("--role <role>", "owner, admin, developer, billing, or viewer", MEMBER_ROLES))
|
|
556
714
|
.action(async (id, opts, cmd) => {
|
|
557
715
|
if (opts.role === undefined) {
|
|
558
|
-
throw new
|
|
716
|
+
throw new CliUsageError("--role is required. Usage: dharta members set-role <id> --role <role>");
|
|
559
717
|
}
|
|
560
718
|
parsePositiveInteger(id, "member id");
|
|
561
719
|
const ctx = await buildContext();
|
|
@@ -575,6 +733,40 @@ export function buildProgram() {
|
|
|
575
733
|
else
|
|
576
734
|
console.log(await membersRemove(ctx, id));
|
|
577
735
|
});
|
|
736
|
+
members
|
|
737
|
+
.command("revoke-invitation <id>")
|
|
738
|
+
.description("Revoke a pending invitation.")
|
|
739
|
+
.action(async (id, _opts, cmd) => {
|
|
740
|
+
parsePositiveInteger(id, "invitation id");
|
|
741
|
+
const ctx = await buildContext();
|
|
742
|
+
if (isJson(cmd))
|
|
743
|
+
printJson(await membersRevokeInvitationData(ctx, id));
|
|
744
|
+
else
|
|
745
|
+
console.log(await membersRevokeInvitation(ctx, id));
|
|
746
|
+
});
|
|
747
|
+
members
|
|
748
|
+
.command("resend-invitation <id>")
|
|
749
|
+
.description("Re-send a pending invitation, keeping the original link.")
|
|
750
|
+
.action(async (id, _opts, cmd) => {
|
|
751
|
+
parsePositiveInteger(id, "invitation id");
|
|
752
|
+
const ctx = await buildContext();
|
|
753
|
+
if (isJson(cmd))
|
|
754
|
+
printJson(await membersResendInvitationData(ctx, id));
|
|
755
|
+
else
|
|
756
|
+
console.log(await membersResendInvitation(ctx, id));
|
|
757
|
+
});
|
|
758
|
+
const repos = program.command("repos").description("Manage hosted source repositories.").action(helpOnlyAction("dharta repos"));
|
|
759
|
+
repos
|
|
760
|
+
.command("disconnect-github <slug>")
|
|
761
|
+
.description("Stop a GitHub repository from producing releases. Live releases are untouched.")
|
|
762
|
+
.action(async (slug, _opts, cmd) => {
|
|
763
|
+
validateAgentSlug(slug, "source repo slug");
|
|
764
|
+
const ctx = await buildContext();
|
|
765
|
+
if (isJson(cmd))
|
|
766
|
+
printJson(await reposDisconnectGithubData(ctx, slug));
|
|
767
|
+
else
|
|
768
|
+
console.log(await reposDisconnectGithub(ctx, slug));
|
|
769
|
+
});
|
|
578
770
|
const kartas = program.command("kartas").description("Manage durable kartas and virtual employees.").action(helpOnlyAction("dharta kartas"));
|
|
579
771
|
kartas
|
|
580
772
|
.command("create <name>")
|
|
@@ -720,7 +912,7 @@ export function buildProgram() {
|
|
|
720
912
|
.addOption(choiceOption("--role <role>", "viewer, participant, or manager", DHARTA_MEMBER_ROLES))
|
|
721
913
|
.action(async (id, membershipId, opts, cmd) => {
|
|
722
914
|
if (opts.role === undefined) {
|
|
723
|
-
throw new
|
|
915
|
+
throw new CliUsageError("--role is required. Usage: dharta kartas set-role <id> <membership-id> --role <role>");
|
|
724
916
|
}
|
|
725
917
|
const ctx = await buildContext();
|
|
726
918
|
if (isJson(cmd))
|
|
@@ -728,6 +920,29 @@ export function buildProgram() {
|
|
|
728
920
|
else
|
|
729
921
|
console.log(await kartaMembersSetRole(ctx, id, membershipId, opts.role));
|
|
730
922
|
});
|
|
923
|
+
kartas
|
|
924
|
+
.command("share <id>")
|
|
925
|
+
.description("Mint a no-sign-in link to a karta and reveal it once.")
|
|
926
|
+
.action(async (id, _opts, cmd) => {
|
|
927
|
+
normalizeNonBlank(id, "karta id");
|
|
928
|
+
const ctx = await buildContext();
|
|
929
|
+
if (isJson(cmd))
|
|
930
|
+
printJson(await kartaShareData(ctx, id));
|
|
931
|
+
else
|
|
932
|
+
console.log(await kartaShare(ctx, id));
|
|
933
|
+
});
|
|
934
|
+
kartas
|
|
935
|
+
.command("unshare <id> <share-id>")
|
|
936
|
+
.description("Revoke a karta share link.")
|
|
937
|
+
.action(async (id, shareId, _opts, cmd) => {
|
|
938
|
+
normalizeNonBlank(id, "karta id");
|
|
939
|
+
normalizeNonBlank(shareId, "share id");
|
|
940
|
+
const ctx = await buildContext();
|
|
941
|
+
if (isJson(cmd))
|
|
942
|
+
printJson(await kartaUnshareData(ctx, id, shareId));
|
|
943
|
+
else
|
|
944
|
+
console.log(await kartaUnshare(ctx, id, shareId));
|
|
945
|
+
});
|
|
731
946
|
kartas
|
|
732
947
|
.command("revoke <id> <membership-id>")
|
|
733
948
|
.description("Remove a person's access to a dharta.")
|
|
@@ -954,7 +1169,7 @@ export function buildProgram() {
|
|
|
954
1169
|
console.log(await appearanceGet(ctx, resolved));
|
|
955
1170
|
});
|
|
956
1171
|
appearanceOpts(appearance.command("set"))
|
|
957
|
-
.description("Merge appearance JSON from a local file.")
|
|
1172
|
+
.description("Merge appearance JSON from a local file. A token set to null in the file is cleared and falls back to the preset.")
|
|
958
1173
|
.option("--file <file>", "JSON file containing appearance tokens")
|
|
959
1174
|
.action(async (_opts, cmd) => {
|
|
960
1175
|
const opts = commandOpts(cmd);
|
|
@@ -1070,6 +1285,262 @@ export function buildProgram() {
|
|
|
1070
1285
|
else
|
|
1071
1286
|
console.log(await directorySessions(ctx, resolved));
|
|
1072
1287
|
});
|
|
1288
|
+
// `fleet` mirrors the fleet console's write side. Reads live under
|
|
1289
|
+
// `directories` and `analytics`; everything here changes something.
|
|
1290
|
+
const fleet = program.command("fleet").description("Run fleet-wide changes, triage, and exports.").action(helpOnlyAction("dharta fleet"));
|
|
1291
|
+
const fleetOperations = fleet.command("operations").description("Preview and apply bulk fleet changes.").action(helpOnlyAction("dharta fleet operations"));
|
|
1292
|
+
fleetOperations
|
|
1293
|
+
.command("create")
|
|
1294
|
+
.description("Freeze a selection into a draft operation. Nothing is applied until you confirm it.")
|
|
1295
|
+
.option("--action <key>", "Action to run, for example set_lifecycle or pause_serving")
|
|
1296
|
+
.option("--entity-type <type>", `Entity type (${FLEET_ENTITY_TYPES.join(", ")})`)
|
|
1297
|
+
.option("--selection-mode <mode>", `How targets are chosen (${FLEET_SELECTION_MODES.join(", ")})`)
|
|
1298
|
+
.option("--id <id...>", "Target row id; repeat for more")
|
|
1299
|
+
.option("--saved-view <id>", "Take the targets from a saved view")
|
|
1300
|
+
.option("--filter <query>", "Take the targets from a catalog filter")
|
|
1301
|
+
.option("--param <key=value...>", "Action parameter; repeat for more")
|
|
1302
|
+
.action(async (opts, cmd) => {
|
|
1303
|
+
const ctx = await buildContext();
|
|
1304
|
+
if (isJson(cmd))
|
|
1305
|
+
printJson(await fleetOperationCreateData(ctx, opts));
|
|
1306
|
+
else
|
|
1307
|
+
console.log(await fleetOperationCreate(ctx, opts));
|
|
1308
|
+
});
|
|
1309
|
+
fleetOperations
|
|
1310
|
+
.command("confirm <id>")
|
|
1311
|
+
.description("Apply a draft operation. Needs fleet:operations:write.")
|
|
1312
|
+
.option("--phrase <phrase>", "The confirmation phrase the draft returned")
|
|
1313
|
+
.action(async (id, opts, cmd) => {
|
|
1314
|
+
const ctx = await buildContext();
|
|
1315
|
+
if (isJson(cmd))
|
|
1316
|
+
printJson(await fleetOperationConfirmData(ctx, id, opts.phrase));
|
|
1317
|
+
else
|
|
1318
|
+
console.log(await fleetOperationConfirm(ctx, id, opts.phrase));
|
|
1319
|
+
});
|
|
1320
|
+
fleetOperations
|
|
1321
|
+
.command("cancel <id>")
|
|
1322
|
+
.description("Stop an operation's remaining targets. Needs fleet:operations:write.")
|
|
1323
|
+
.action(async (id, _opts, cmd) => {
|
|
1324
|
+
const ctx = await buildContext();
|
|
1325
|
+
if (isJson(cmd))
|
|
1326
|
+
printJson(await fleetOperationCancelData(ctx, id));
|
|
1327
|
+
else
|
|
1328
|
+
console.log(await fleetOperationCancel(ctx, id));
|
|
1329
|
+
});
|
|
1330
|
+
fleetOperations
|
|
1331
|
+
.command("retry <id>")
|
|
1332
|
+
.description("Requeue only the failed targets. Needs fleet:operations:write.")
|
|
1333
|
+
.action(async (id, _opts, cmd) => {
|
|
1334
|
+
const ctx = await buildContext();
|
|
1335
|
+
if (isJson(cmd))
|
|
1336
|
+
printJson(await fleetOperationRetryData(ctx, id));
|
|
1337
|
+
else
|
|
1338
|
+
console.log(await fleetOperationRetry(ctx, id));
|
|
1339
|
+
});
|
|
1340
|
+
const fleetRollouts = fleet.command("rollouts").description("Drive a staged release rollout.").action(helpOnlyAction("dharta fleet rollouts"));
|
|
1341
|
+
// Every rollout verb needs fleet:operations:write, not just the two the
|
|
1342
|
+
// console gates with a step-up: pausing or resuming a release mid-flight
|
|
1343
|
+
// moves live releases the same way advancing it does.
|
|
1344
|
+
for (const [verb, description] of [
|
|
1345
|
+
["advance", "Move the rollout to its next ring. Needs fleet:operations:write."],
|
|
1346
|
+
["pause", "Hold the rollout where it is. Needs fleet:operations:write."],
|
|
1347
|
+
["resume", "Resume a paused rollout. Needs fleet:operations:write."],
|
|
1348
|
+
[
|
|
1349
|
+
"evaluate",
|
|
1350
|
+
"Run the health evaluation now instead of waiting for the window. Needs fleet:operations:write.",
|
|
1351
|
+
],
|
|
1352
|
+
]) {
|
|
1353
|
+
fleetRollouts
|
|
1354
|
+
.command(`${verb} <id>`)
|
|
1355
|
+
.description(description)
|
|
1356
|
+
.action(async (id, _opts, cmd) => {
|
|
1357
|
+
const ctx = await buildContext();
|
|
1358
|
+
if (isJson(cmd))
|
|
1359
|
+
printJson(await fleetRolloutData(ctx, verb, id));
|
|
1360
|
+
else
|
|
1361
|
+
console.log(await fleetRollout(ctx, verb, id));
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
fleetRollouts
|
|
1365
|
+
.command("rollback <id>")
|
|
1366
|
+
.description("Revert every target to the previous release. Needs fleet:operations:write.")
|
|
1367
|
+
.action(async (id, _opts, cmd) => {
|
|
1368
|
+
const ctx = await buildContext();
|
|
1369
|
+
if (isJson(cmd))
|
|
1370
|
+
printJson(await fleetRolloutRollbackData(ctx, id));
|
|
1371
|
+
else
|
|
1372
|
+
console.log(await fleetRolloutRollback(ctx, id));
|
|
1373
|
+
});
|
|
1374
|
+
const fleetFindings = fleet.command("findings").description("Triage anomaly findings.").action(helpOnlyAction("dharta fleet findings"));
|
|
1375
|
+
for (const [verb, description] of [
|
|
1376
|
+
["acknowledge", "Take ownership of a finding."],
|
|
1377
|
+
["resolve", "Close a finding."],
|
|
1378
|
+
["reopen", "Reopen a resolved or snoozed finding."],
|
|
1379
|
+
["promote", "Raise a finding to an incident."],
|
|
1380
|
+
]) {
|
|
1381
|
+
fleetFindings
|
|
1382
|
+
.command(`${verb} <id>`)
|
|
1383
|
+
.description(description)
|
|
1384
|
+
.action(async (id, _opts, cmd) => {
|
|
1385
|
+
const ctx = await buildContext();
|
|
1386
|
+
if (isJson(cmd))
|
|
1387
|
+
printJson(await fleetFindingData(ctx, verb, id));
|
|
1388
|
+
else
|
|
1389
|
+
console.log(await fleetFinding(ctx, verb, id));
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
fleetFindings
|
|
1393
|
+
.command("snooze <id>")
|
|
1394
|
+
.description("Hide a finding until the window is up.")
|
|
1395
|
+
.option("--duration <window>", `Snooze window (${FLEET_SNOOZE_DURATIONS.join(", ")})`)
|
|
1396
|
+
.action(async (id, opts, cmd) => {
|
|
1397
|
+
const ctx = await buildContext();
|
|
1398
|
+
if (isJson(cmd))
|
|
1399
|
+
printJson(await fleetFindingSnoozeData(ctx, id, opts));
|
|
1400
|
+
else
|
|
1401
|
+
console.log(await fleetFindingSnooze(ctx, id, opts));
|
|
1402
|
+
});
|
|
1403
|
+
fleetFindings
|
|
1404
|
+
.command("classify <id>")
|
|
1405
|
+
.description("Record what a finding turned out to be.")
|
|
1406
|
+
.option("--as <classification>", "Classification to record")
|
|
1407
|
+
.action(async (id, opts, cmd) => {
|
|
1408
|
+
const ctx = await buildContext();
|
|
1409
|
+
if (isJson(cmd))
|
|
1410
|
+
printJson(await fleetFindingClassifyData(ctx, id, opts));
|
|
1411
|
+
else
|
|
1412
|
+
console.log(await fleetFindingClassify(ctx, id, opts));
|
|
1413
|
+
});
|
|
1414
|
+
fleetFindings
|
|
1415
|
+
.command("assign <id>")
|
|
1416
|
+
.description("Assign a finding to a member, or clear the owner.")
|
|
1417
|
+
.option("--membership-id <id>", "Organization membership id to assign")
|
|
1418
|
+
.option("--unassign", "Clear the current owner")
|
|
1419
|
+
.action(async (id, opts, cmd) => {
|
|
1420
|
+
const ctx = await buildContext();
|
|
1421
|
+
if (isJson(cmd))
|
|
1422
|
+
printJson(await fleetFindingAssignData(ctx, id, opts));
|
|
1423
|
+
else
|
|
1424
|
+
console.log(await fleetFindingAssign(ctx, id, opts));
|
|
1425
|
+
});
|
|
1426
|
+
fleetFindings
|
|
1427
|
+
.command("update <id>")
|
|
1428
|
+
.description("Set or clear a finding's runbook link.")
|
|
1429
|
+
.option("--runbook-url <url>", "Runbook URL; pass an empty string to clear")
|
|
1430
|
+
.action(async (id, opts, cmd) => {
|
|
1431
|
+
const ctx = await buildContext();
|
|
1432
|
+
if (isJson(cmd))
|
|
1433
|
+
printJson(await fleetFindingUpdateData(ctx, id, opts));
|
|
1434
|
+
else
|
|
1435
|
+
console.log(await fleetFindingUpdate(ctx, id, opts));
|
|
1436
|
+
});
|
|
1437
|
+
const fleetViews = fleet.command("views").description("Manage saved fleet views.").action(helpOnlyAction("dharta fleet views"));
|
|
1438
|
+
const viewWriteOpts = (cmd) => cmd
|
|
1439
|
+
.option("--entity-type <type>", "Entity type the view lists")
|
|
1440
|
+
.option("--name <name>", "View name")
|
|
1441
|
+
.option("--definition <json>", "Filters, columns and sort, as a JSON object")
|
|
1442
|
+
.option("--description <text>", "What the view is for")
|
|
1443
|
+
.option("--visibility <level>", `Who can see it (${FLEET_VIEW_VISIBILITIES.join(", ")})`)
|
|
1444
|
+
.option("--team-id <id>", "Owning team, for team visibility")
|
|
1445
|
+
.option("--organization-default", "Make it the organization's default view");
|
|
1446
|
+
viewWriteOpts(fleetViews.command("create"))
|
|
1447
|
+
.description("Create a saved view.")
|
|
1448
|
+
.action(async (opts, cmd) => {
|
|
1449
|
+
const ctx = await buildContext();
|
|
1450
|
+
if (isJson(cmd))
|
|
1451
|
+
printJson(await fleetViewCreateData(ctx, opts));
|
|
1452
|
+
else
|
|
1453
|
+
console.log(await fleetViewCreate(ctx, opts));
|
|
1454
|
+
});
|
|
1455
|
+
viewWriteOpts(fleetViews.command("update <id>"))
|
|
1456
|
+
.description("Change a saved view.")
|
|
1457
|
+
.action(async (id, opts, cmd) => {
|
|
1458
|
+
const ctx = await buildContext();
|
|
1459
|
+
if (isJson(cmd))
|
|
1460
|
+
printJson(await fleetViewUpdateData(ctx, id, opts));
|
|
1461
|
+
else
|
|
1462
|
+
console.log(await fleetViewUpdate(ctx, id, opts));
|
|
1463
|
+
});
|
|
1464
|
+
fleetViews
|
|
1465
|
+
.command("delete <id>")
|
|
1466
|
+
.alias("rm")
|
|
1467
|
+
.description("Delete a saved view.")
|
|
1468
|
+
.action(async (id, _opts, cmd) => {
|
|
1469
|
+
const ctx = await buildContext();
|
|
1470
|
+
if (isJson(cmd))
|
|
1471
|
+
printJson(await fleetViewDeleteData(ctx, id));
|
|
1472
|
+
else
|
|
1473
|
+
console.log(await fleetViewDelete(ctx, id));
|
|
1474
|
+
});
|
|
1475
|
+
fleetViews
|
|
1476
|
+
.command("favorite <id>")
|
|
1477
|
+
.description("Favorite a saved view for the key's owner.")
|
|
1478
|
+
.action(async (id, _opts, cmd) => {
|
|
1479
|
+
const ctx = await buildContext();
|
|
1480
|
+
if (isJson(cmd))
|
|
1481
|
+
printJson(await fleetViewFavoriteData(ctx, id));
|
|
1482
|
+
else
|
|
1483
|
+
console.log(await fleetViewFavorite(ctx, id));
|
|
1484
|
+
});
|
|
1485
|
+
fleetViews
|
|
1486
|
+
.command("unfavorite <id>")
|
|
1487
|
+
.description("Remove a saved view from the key owner's favorites.")
|
|
1488
|
+
.action(async (id, _opts, cmd) => {
|
|
1489
|
+
const ctx = await buildContext();
|
|
1490
|
+
if (isJson(cmd))
|
|
1491
|
+
printJson(await fleetViewUnfavoriteData(ctx, id));
|
|
1492
|
+
else
|
|
1493
|
+
console.log(await fleetViewUnfavorite(ctx, id));
|
|
1494
|
+
});
|
|
1495
|
+
const fleetAnalytics = fleet.command("analytics").description("Save and unpin Analytics charts.").action(helpOnlyAction("dharta fleet analytics"));
|
|
1496
|
+
fleetAnalytics
|
|
1497
|
+
.command("save")
|
|
1498
|
+
.description("Save an explorer chart and pin it to your Analytics list.")
|
|
1499
|
+
.option("--name <name>", "Chart name")
|
|
1500
|
+
.option("--metric <metric>", "Metric to chart. Defaults to turns.")
|
|
1501
|
+
.option("--description <text>", "What the chart shows")
|
|
1502
|
+
.option("--range <range>", "Time range, for example 30d")
|
|
1503
|
+
.option("--starts-at <timestamp>", "Custom range start")
|
|
1504
|
+
.option("--ends-at <timestamp>", "Custom range end")
|
|
1505
|
+
.option("--scope-kind <kind>", "Scope the chart to a kind of row")
|
|
1506
|
+
.option("--scope-ids <ids>", "Comma-separated scope ids")
|
|
1507
|
+
.option("--bucket <bucket>", "Time bucket, for example day")
|
|
1508
|
+
.option("--aggregation <aggregation>", "How values are combined")
|
|
1509
|
+
.option("--comparison <comparison>", "Comparison series to draw")
|
|
1510
|
+
.option("--comparison-saved-view <id>", "Saved cohort to compare against")
|
|
1511
|
+
.option("--breakdown <field...>", "Break the series down by a field; repeat for more")
|
|
1512
|
+
.option("--event <type...>", "Event type to include; repeat for more")
|
|
1513
|
+
.option("--filter <key=value...>", "Filter; repeat for more")
|
|
1514
|
+
.action(async (opts, cmd) => {
|
|
1515
|
+
const ctx = await buildContext();
|
|
1516
|
+
if (isJson(cmd))
|
|
1517
|
+
printJson(await fleetAnalyticsSaveData(ctx, opts));
|
|
1518
|
+
else
|
|
1519
|
+
console.log(await fleetAnalyticsSave(ctx, opts));
|
|
1520
|
+
});
|
|
1521
|
+
fleetAnalytics
|
|
1522
|
+
.command("unpin <id>")
|
|
1523
|
+
.description("Remove a chart from your Analytics list. The saved view survives.")
|
|
1524
|
+
.action(async (id, _opts, cmd) => {
|
|
1525
|
+
const ctx = await buildContext();
|
|
1526
|
+
if (isJson(cmd))
|
|
1527
|
+
printJson(await fleetAnalyticsUnpinData(ctx, id));
|
|
1528
|
+
else
|
|
1529
|
+
console.log(await fleetAnalyticsUnpin(ctx, id));
|
|
1530
|
+
});
|
|
1531
|
+
const fleetExports = fleet.command("exports").description("Export catalog rows as CSV.").action(helpOnlyAction("dharta fleet exports"));
|
|
1532
|
+
fleetExports
|
|
1533
|
+
.command("create")
|
|
1534
|
+
.description("Write the named rows to stdout as CSV.")
|
|
1535
|
+
.option("--entity-type <type>", `Entity type (${FLEET_ENTITY_TYPES.join(", ")})`)
|
|
1536
|
+
.option("--id <id...>", "Row id to export; repeat for more")
|
|
1537
|
+
.action(async (opts, cmd) => {
|
|
1538
|
+
const ctx = await buildContext();
|
|
1539
|
+
if (isJson(cmd))
|
|
1540
|
+
printJson(await fleetExportCreateData(ctx, opts));
|
|
1541
|
+
else
|
|
1542
|
+
console.log(await fleetExportCreate(ctx, opts));
|
|
1543
|
+
});
|
|
1073
1544
|
const webhooks = program.command("webhooks").description("Manage webhook endpoints.").action(helpOnlyAction("dharta webhooks"));
|
|
1074
1545
|
webhooks
|
|
1075
1546
|
.command("list")
|
|
@@ -1120,6 +1591,17 @@ export function buildProgram() {
|
|
|
1120
1591
|
else
|
|
1121
1592
|
console.log(await webhooksEnable(ctx, id));
|
|
1122
1593
|
});
|
|
1594
|
+
webhooks
|
|
1595
|
+
.command("test <id>")
|
|
1596
|
+
.description("Send one test event through the real delivery path.")
|
|
1597
|
+
.action(async (id, _opts, cmd) => {
|
|
1598
|
+
normalizeNonBlank(id, "Webhook endpoint id");
|
|
1599
|
+
const ctx = await buildContext();
|
|
1600
|
+
if (isJson(cmd))
|
|
1601
|
+
printJson(await webhooksTestData(ctx, id));
|
|
1602
|
+
else
|
|
1603
|
+
console.log(await webhooksTest(ctx, id));
|
|
1604
|
+
});
|
|
1123
1605
|
webhooks
|
|
1124
1606
|
.command("delete <id>")
|
|
1125
1607
|
.alias("rm")
|
|
@@ -1168,6 +1650,7 @@ export function buildProgram() {
|
|
|
1168
1650
|
.option("--user <id>", "Simulate a verified end user (per-user memory behavior)")
|
|
1169
1651
|
.option("--port <port>", "Serve the local agent API on a stable port (for widgets/frontends)")
|
|
1170
1652
|
.option("--verbose", "Stream agent-runtime output and parity details")
|
|
1653
|
+
.addOption(choiceOption("--model-auth <method>", "Anthropic authentication: api-key or claude", DEV_MODEL_AUTH_VALUES))
|
|
1171
1654
|
.option("--release <vN>", "Run the exact built tree prod serves (audited archive pull)")
|
|
1172
1655
|
.addOption(choiceOption("--env <mode>", "Bind prod env vars instead of .env", ["remote"]))
|
|
1173
1656
|
.option("--include-secrets", "With --env remote: fetch secret values (requires env:secrets:read; audited)")
|
|
@@ -1175,7 +1658,7 @@ export function buildProgram() {
|
|
|
1175
1658
|
.action(async (pathArg, opts, cmd) => {
|
|
1176
1659
|
rejectJson(cmd, "dharta dev");
|
|
1177
1660
|
if (pathArg !== undefined && opts.dir !== undefined) {
|
|
1178
|
-
throw new
|
|
1661
|
+
throw new CliUsageError("Use either [path] or --dir, not both.");
|
|
1179
1662
|
}
|
|
1180
1663
|
const dir = pathArg !== undefined
|
|
1181
1664
|
? normalizeNonBlank(pathArg, "path")
|
|
@@ -1185,7 +1668,7 @@ export function buildProgram() {
|
|
|
1185
1668
|
if (opts.release !== undefined)
|
|
1186
1669
|
parseReleaseVersion(opts.release, "--release");
|
|
1187
1670
|
if (opts.includeSecrets && opts.env !== "remote") {
|
|
1188
|
-
throw new
|
|
1671
|
+
throw new CliUsageError("--include-secrets requires --env remote.");
|
|
1189
1672
|
}
|
|
1190
1673
|
validateAgentSelectorOptions({ agent: opts.agent, project: opts.project });
|
|
1191
1674
|
await devCmd({
|
|
@@ -1193,6 +1676,7 @@ export function buildProgram() {
|
|
|
1193
1676
|
message: opts.message,
|
|
1194
1677
|
user: opts.user,
|
|
1195
1678
|
verbose: opts.verbose,
|
|
1679
|
+
modelAuth: opts.modelAuth,
|
|
1196
1680
|
port: opts.port ? parsePort(opts.port) : undefined,
|
|
1197
1681
|
release: opts.release,
|
|
1198
1682
|
envRemote: opts.env === "remote",
|
|
@@ -1201,6 +1685,7 @@ export function buildProgram() {
|
|
|
1201
1685
|
});
|
|
1202
1686
|
});
|
|
1203
1687
|
registerArtifactCommands(program);
|
|
1688
|
+
registerGenuiCommands(program);
|
|
1204
1689
|
const sessionsOpts = (cmd) => cmd
|
|
1205
1690
|
.option("-a, --agent <slug>", "Agent slug (default: the agent in this folder)")
|
|
1206
1691
|
.option("-p, --project <slug>", "Alias of --agent")
|
|
@@ -1522,9 +2007,8 @@ export function buildProgram() {
|
|
|
1522
2007
|
.option("-a, --agent <slug>", "Agent slug (default: the agent in this folder)")
|
|
1523
2008
|
.option("-p, --project <slug>", "Alias of --agent")
|
|
1524
2009
|
.option("--dir <dir>", "Directory to resolve the agent from (default: current directory)")
|
|
1525
|
-
.
|
|
1526
|
-
.option("--
|
|
1527
|
-
.option("--model <model>", "Provider model id")
|
|
2010
|
+
.option("--connector <slugs>", "Ordered connection slugs from `dharta models auth list`; use karta for the platform connection or an empty string to inherit")
|
|
2011
|
+
.option("--model-ref <reference>", "Model reference: <model>, connector:<slug>/<model>, or an empty string for the connector default")
|
|
1528
2012
|
.option("--temperature <number>", "Sampling temperature from 0 to 2")
|
|
1529
2013
|
.option("--clear-temperature", "Inherit temperature")
|
|
1530
2014
|
.option("--top-p <number>", "Nucleus sampling probability above 0 and at most 1")
|
|
@@ -1597,6 +2081,113 @@ export function buildProgram() {
|
|
|
1597
2081
|
else
|
|
1598
2082
|
console.log(await agentsWorkspaceAccessSet(ctx, resolved, patch));
|
|
1599
2083
|
});
|
|
2084
|
+
agent
|
|
2085
|
+
.command("rename <name> [slug]")
|
|
2086
|
+
.description("Change an agent's display name; the slug stays as it is.")
|
|
2087
|
+
.option("-a, --agent <slug>", "Agent slug (default: the agent in this folder)")
|
|
2088
|
+
.option("-p, --project <slug>", "Alias of --agent")
|
|
2089
|
+
.option("--dir <dir>", "Agent directory (default: current directory)")
|
|
2090
|
+
.action(async (name, slugArg, _opts, cmd) => {
|
|
2091
|
+
const opts = commandOpts(cmd);
|
|
2092
|
+
const resolvedOpts = await resolveAgentOptions(opts, slugArg);
|
|
2093
|
+
const ctx = await buildContext();
|
|
2094
|
+
const resolved = resolvedOpts.agent;
|
|
2095
|
+
if (isJson(cmd))
|
|
2096
|
+
printJson(await agentsRenameData(ctx, resolved, name));
|
|
2097
|
+
else
|
|
2098
|
+
console.log(await agentsRename(ctx, resolved, name));
|
|
2099
|
+
});
|
|
2100
|
+
agent
|
|
2101
|
+
.command("durable-workspace <state> [slug]")
|
|
2102
|
+
.description(`Enable or disable the durable workspace for an agent's kartas - a cost setting, since durable storage is billed per GB. ${STATE_HELP}`)
|
|
2103
|
+
.option("-a, --agent <slug>", "Agent slug (default: the agent in this folder)")
|
|
2104
|
+
.option("-p, --project <slug>", "Alias of --agent")
|
|
2105
|
+
.option("--dir <dir>", "Agent directory (default: current directory)")
|
|
2106
|
+
.action(async (state, slugArg, _opts, cmd) => {
|
|
2107
|
+
const opts = commandOpts(cmd);
|
|
2108
|
+
const enabled = parseOnOff(state, "state");
|
|
2109
|
+
const resolvedOpts = await resolveAgentOptions(opts, slugArg);
|
|
2110
|
+
const ctx = await buildContext();
|
|
2111
|
+
const resolved = resolvedOpts.agent;
|
|
2112
|
+
if (isJson(cmd))
|
|
2113
|
+
printJson(await agentsDurableWorkspaceSetData(ctx, resolved, enabled));
|
|
2114
|
+
else
|
|
2115
|
+
console.log(await agentsDurableWorkspaceSet(ctx, resolved, enabled));
|
|
2116
|
+
});
|
|
2117
|
+
agent
|
|
2118
|
+
.command("create [name]")
|
|
2119
|
+
.description("Create a hosted agent, or link an installed GitHub repository as its source with --github-repo. `dharta create` scaffolds locally instead.")
|
|
2120
|
+
.option("--slug <slug>", "Agent or source-repo slug (default: derived from the name or repository)")
|
|
2121
|
+
.option("--github-repo <repo>", "Installed GitHub repository to link as the source of truth, by id or owner/name (see `dharta agent github-repos`)")
|
|
2122
|
+
.option("--branch <branch>", "Deploy branch for the linked repository; needs --github-repo")
|
|
2123
|
+
.action(async (name, _opts, cmd) => {
|
|
2124
|
+
const opts = commandOpts(cmd);
|
|
2125
|
+
validateAgentCreateInput(name, opts);
|
|
2126
|
+
const ctx = await buildContext();
|
|
2127
|
+
if (isJson(cmd))
|
|
2128
|
+
printJson(await agentsCreateData(ctx, name, opts));
|
|
2129
|
+
else
|
|
2130
|
+
console.log(await agentsCreate(ctx, name, opts));
|
|
2131
|
+
});
|
|
2132
|
+
agent
|
|
2133
|
+
.command("github-repos")
|
|
2134
|
+
.description("List the GitHub repositories the Dharta App is installed on, with the ids `--github-repo` takes.")
|
|
2135
|
+
.action(async (_opts, cmd) => {
|
|
2136
|
+
const ctx = await buildContext();
|
|
2137
|
+
if (isJson(cmd))
|
|
2138
|
+
printJson(await agentsGithubReposData(ctx));
|
|
2139
|
+
else
|
|
2140
|
+
console.log(await agentsGithubRepos(ctx));
|
|
2141
|
+
});
|
|
2142
|
+
agent
|
|
2143
|
+
.command("create-from-template <template> <name>")
|
|
2144
|
+
.description("Create a hosted agent from a built-in template and publish its first release. `dharta create` scaffolds locally instead.")
|
|
2145
|
+
.option("--slug <slug>", "Agent slug (default: derived from the name)")
|
|
2146
|
+
.option("--description <text>", "Short description")
|
|
2147
|
+
.option("--harness <type>", "Harness slug (default: Dharta's curated default)")
|
|
2148
|
+
.option("--harness-version <version>", "Harness version; needs --harness")
|
|
2149
|
+
.action(async (template, name, _opts, cmd) => {
|
|
2150
|
+
const opts = commandOpts(cmd);
|
|
2151
|
+
validateAgentCreateFromTemplateInput(template, name, opts);
|
|
2152
|
+
const ctx = await buildContext();
|
|
2153
|
+
if (isJson(cmd))
|
|
2154
|
+
printJson(await agentsCreateFromTemplateData(ctx, template, name, opts));
|
|
2155
|
+
else
|
|
2156
|
+
console.log(await agentsCreateFromTemplate(ctx, template, name, opts));
|
|
2157
|
+
});
|
|
2158
|
+
agent
|
|
2159
|
+
.command("redeploy [slug]")
|
|
2160
|
+
.description("Re-sync a GitHub-connected agent and rebuild it from deploy-branch HEAD.")
|
|
2161
|
+
.option("-a, --agent <slug>", "Agent slug (default: the agent in this folder)")
|
|
2162
|
+
.option("-p, --project <slug>", "Alias of --agent")
|
|
2163
|
+
.option("--dir <dir>", "Agent directory (default: current directory)")
|
|
2164
|
+
.action(async (slugArg, _opts, cmd) => {
|
|
2165
|
+
const opts = commandOpts(cmd);
|
|
2166
|
+
const resolvedOpts = await resolveAgentOptions(opts, slugArg);
|
|
2167
|
+
const ctx = await buildContext();
|
|
2168
|
+
const resolved = resolvedOpts.agent;
|
|
2169
|
+
if (isJson(cmd))
|
|
2170
|
+
printJson(await agentsRedeployData(ctx, resolved));
|
|
2171
|
+
else
|
|
2172
|
+
console.log(await agentsRedeploy(ctx, resolved));
|
|
2173
|
+
});
|
|
2174
|
+
agent
|
|
2175
|
+
.command("retry <version> [slug]")
|
|
2176
|
+
.description("Retry a failed browser-created release; it republishes as the next version.")
|
|
2177
|
+
.option("-a, --agent <slug>", "Agent slug (default: the agent in this folder)")
|
|
2178
|
+
.option("-p, --project <slug>", "Alias of --agent")
|
|
2179
|
+
.option("--dir <dir>", "Agent directory (default: current directory)")
|
|
2180
|
+
.action(async (version, slugArg, _opts, cmd) => {
|
|
2181
|
+
const opts = commandOpts(cmd);
|
|
2182
|
+
parseVersion(version);
|
|
2183
|
+
const resolvedOpts = await resolveAgentOptions(opts, slugArg);
|
|
2184
|
+
const ctx = await buildContext();
|
|
2185
|
+
const resolved = resolvedOpts.agent;
|
|
2186
|
+
if (isJson(cmd))
|
|
2187
|
+
printJson(await agentsRetryReleaseData(ctx, resolved, version));
|
|
2188
|
+
else
|
|
2189
|
+
console.log(await agentsRetryRelease(ctx, resolved, version));
|
|
2190
|
+
});
|
|
1600
2191
|
agent
|
|
1601
2192
|
.command("delete [slug]")
|
|
1602
2193
|
.description("Archive an agent.")
|
|
@@ -1630,13 +2221,13 @@ export function buildProgram() {
|
|
|
1630
2221
|
// owner of target/config resolution and can narrate legacy inference.
|
|
1631
2222
|
const mode = rawMode ?? (await inferMode(dir));
|
|
1632
2223
|
if (opts.reconcileSource && mode !== "git") {
|
|
1633
|
-
throw new
|
|
2224
|
+
throw new CliUsageError("--reconcile-source is only valid for git deploys. " +
|
|
1634
2225
|
"Remove it, or use `--mode git` to reconcile Dharta's hosted source branch.");
|
|
1635
2226
|
}
|
|
1636
2227
|
// git mode's output is the live push sideband, not a payload.
|
|
1637
2228
|
const json = mode === "folder" && isJson(cmd);
|
|
1638
2229
|
if (mode === "git" && isJson(cmd)) {
|
|
1639
|
-
throw new
|
|
2230
|
+
throw new CliUsageError("--json is only supported for `dharta deploy --mode folder`; git deploy streams git push output. Run `dharta deploy` without --json or pass `--mode folder`.");
|
|
1640
2231
|
}
|
|
1641
2232
|
const ctx = await buildContext();
|
|
1642
2233
|
const result = await deploy(ctx, slug, {
|
|
@@ -1659,7 +2250,7 @@ export function buildProgram() {
|
|
|
1659
2250
|
const slug = opts.agent ?? opts.project ?? "";
|
|
1660
2251
|
if (slug.trim())
|
|
1661
2252
|
validateAgentSlug(slug, opts.agent !== undefined ? "--agent" : "--project");
|
|
1662
|
-
throw new
|
|
2253
|
+
throw new CliUsageError("`dharta status` is repo-wide. Use `dharta agent show <slug>` for one remote agent, or `dharta status --dir <path>` for a local repo.");
|
|
1663
2254
|
}
|
|
1664
2255
|
validateAgentSelectorOptions(opts);
|
|
1665
2256
|
let ctx = null;
|
|
@@ -1668,7 +2259,7 @@ export function buildProgram() {
|
|
|
1668
2259
|
ctx = await buildContext();
|
|
1669
2260
|
}
|
|
1670
2261
|
catch (err) {
|
|
1671
|
-
if (!
|
|
2262
|
+
if (!isNotAuthenticatedError(err))
|
|
1672
2263
|
throw err;
|
|
1673
2264
|
authMessage = err instanceof Error ? err.message : String(err);
|
|
1674
2265
|
}
|
|
@@ -1728,23 +2319,138 @@ export function buildProgram() {
|
|
|
1728
2319
|
// commands and help-only command groups keep a hidden parser option
|
|
1729
2320
|
// because they reject --json.
|
|
1730
2321
|
for (const cmd of allCommands(program)) {
|
|
2322
|
+
const jq = new Option("--jq <expr>", "Filter the JSON result through jq (implies --json)");
|
|
1731
2323
|
if (hidesJsonHelp(cmd)) {
|
|
1732
2324
|
cmd.addOption(new Option("--json", "Print the result as JSON (machine-readable)").hideHelp());
|
|
2325
|
+
cmd.addOption(jq.hideHelp());
|
|
1733
2326
|
}
|
|
1734
2327
|
else {
|
|
1735
2328
|
cmd.option("--json", jsonHelpDescription(cmd));
|
|
2329
|
+
cmd.addOption(jq);
|
|
1736
2330
|
}
|
|
2331
|
+
// --profile rides the same mechanic: registered on every node so the flag
|
|
2332
|
+
// parses wherever it appears on the line, read back through
|
|
2333
|
+
// optsWithGlobals(). Hidden on the pure command groups, which only print
|
|
2334
|
+
// help and never resolve a credential.
|
|
2335
|
+
const profile = new Option("--profile <name>", "Profile in ~/.dharta/config.toml to use (env: DHARTA_PROFILE)");
|
|
2336
|
+
if (HELP_ONLY_COMMAND_PATHS.has(commandPath(cmd)) && cmd.parent !== null)
|
|
2337
|
+
profile.hideHelp();
|
|
2338
|
+
cmd.addOption(profile);
|
|
2339
|
+
// --idempotency-key rides the same mechanic for the same reason: it has to
|
|
2340
|
+
// parse wherever it sits on the line, and one flag has to reach every
|
|
2341
|
+
// request the run makes. Hidden on the help-only groups, which issue none.
|
|
2342
|
+
const idempotencyKey = new Option("--idempotency-key <key>", "Send this Idempotency-Key on every request the command makes");
|
|
2343
|
+
if (HELP_ONLY_COMMAND_PATHS.has(commandPath(cmd)) && cmd.parent !== null)
|
|
2344
|
+
idempotencyKey.hideHelp();
|
|
2345
|
+
cmd.addOption(idempotencyKey);
|
|
1737
2346
|
}
|
|
2347
|
+
// One place decides the active profile for the whole run. preAction hooks are
|
|
2348
|
+
// inherited by every subcommand, so this fires exactly once, before the
|
|
2349
|
+
// action, with the flag resolved from wherever it sat on the command line.
|
|
2350
|
+
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
2351
|
+
const opts = actionCommand.optsWithGlobals();
|
|
2352
|
+
setRequestedProfile(opts.profile);
|
|
2353
|
+
rejectNonMutatingIdempotencyKey(actionCommand, opts.idempotencyKey);
|
|
2354
|
+
setRequestedIdempotencyKey(opts.idempotencyKey);
|
|
2355
|
+
resetJsonPayload();
|
|
2356
|
+
// Compile the filter before the action runs, so a typo costs nothing.
|
|
2357
|
+
await armJqFilter(opts.jq);
|
|
2358
|
+
});
|
|
2359
|
+
// The filtered payload is written after the action resolves. postAction runs
|
|
2360
|
+
// for every entry point (parseAsync from the bin, or straight from a test),
|
|
2361
|
+
// and does not run when the action threw - which is right, because a failed
|
|
2362
|
+
// command has no payload to filter.
|
|
2363
|
+
program.hook("postAction", async () => {
|
|
2364
|
+
await flushJsonPayload();
|
|
2365
|
+
});
|
|
2366
|
+
assignTopLevelHelpGroups(program);
|
|
1738
2367
|
installMissingArgumentChoiceHints(program);
|
|
1739
2368
|
installTopLevelUnknownCommandGuard(program);
|
|
2369
|
+
installExitOverride(program);
|
|
1740
2370
|
return program;
|
|
1741
2371
|
}
|
|
1742
|
-
|
|
1743
|
-
|
|
2372
|
+
// The root help used to carry a hand-written, hand-ordered list of commands in
|
|
2373
|
+
// addHelpText, with commander's own list suppressed - two surfaces to keep in
|
|
2374
|
+
// step, and the list drifted (`files` and `artifact` were never in it).
|
|
2375
|
+
// Commander 15 groups natively, so the groups are declared here, on the tree,
|
|
2376
|
+
// and both `dharta --help` and the generated docs reference read them from it.
|
|
2377
|
+
export const TOP_LEVEL_HELP_GROUPS = [
|
|
2378
|
+
["Setup and auth", ["login", "auth", "whoami", "create", "setup"]],
|
|
2379
|
+
["Local and deploy", ["dev", "deploy", "status", "rollback", "logs"]],
|
|
2380
|
+
["Runtime operations", ["open", "sessions", "session", "ps", "send", "files", "artifact", "schedules"]],
|
|
2381
|
+
["Agent configuration", ["agent", "env", "appearance", "genui"]],
|
|
2382
|
+
[
|
|
2383
|
+
"Management",
|
|
2384
|
+
[
|
|
2385
|
+
"usage",
|
|
2386
|
+
"analytics",
|
|
2387
|
+
"directories",
|
|
2388
|
+
"fleet",
|
|
2389
|
+
"kartas",
|
|
2390
|
+
"caps",
|
|
2391
|
+
"embed-keys",
|
|
2392
|
+
"webhooks",
|
|
2393
|
+
"audit-log",
|
|
2394
|
+
"keys",
|
|
2395
|
+
"models",
|
|
2396
|
+
"org",
|
|
2397
|
+
"members",
|
|
2398
|
+
"repos",
|
|
2399
|
+
"api",
|
|
2400
|
+
],
|
|
2401
|
+
],
|
|
2402
|
+
["Utilities", ["doctor", "update", "completion"]],
|
|
2403
|
+
];
|
|
2404
|
+
function assignTopLevelHelpGroups(program) {
|
|
2405
|
+
const order = new Map();
|
|
2406
|
+
for (const [group, names] of TOP_LEVEL_HELP_GROUPS) {
|
|
2407
|
+
for (const name of names) {
|
|
2408
|
+
const cmd = program.commands.find((candidate) => candidate.name() === name);
|
|
2409
|
+
if (!cmd) {
|
|
2410
|
+
throw new Error(`Help group '${group}' names '${name}', which is not a top-level command.`);
|
|
2411
|
+
}
|
|
2412
|
+
cmd.helpGroup(`${group}:`);
|
|
2413
|
+
order.set(name, order.size);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
// Commander discovers group headings in registration order, so the array
|
|
2417
|
+
// itself has to be in group order for the help to read top to bottom.
|
|
2418
|
+
// Ungrouped (hidden) commands keep their place at the end. The array is
|
|
2419
|
+
// typed readonly but is the live list commander renders from, so sorting it
|
|
2420
|
+
// is the ordering hook - there is no public setter.
|
|
2421
|
+
program.commands.sort((a, b) => (order.get(a.name()) ?? Number.MAX_SAFE_INTEGER) - (order.get(b.name()) ?? Number.MAX_SAFE_INTEGER));
|
|
2422
|
+
}
|
|
2423
|
+
// Commander calls process.exit(1) itself for a bad flag, which flattens every
|
|
2424
|
+
// usage mistake into the same code as a failed API call. exitOverride makes it
|
|
2425
|
+
// throw instead, so the single catch in the bin block maps it to EXIT_USAGE.
|
|
2426
|
+
// The setting is per-command, not inherited, so every node gets it.
|
|
2427
|
+
function installExitOverride(program) {
|
|
2428
|
+
for (const cmd of allCommands(program))
|
|
2429
|
+
cmd.exitOverride();
|
|
1744
2430
|
}
|
|
1745
2431
|
export async function main(argv) {
|
|
1746
2432
|
await buildProgram().parseAsync(argv);
|
|
1747
2433
|
}
|
|
2434
|
+
// The single place a failure turns into an exit status. Returns the code so
|
|
2435
|
+
// the bin block can `process.exit` with it; commander has already printed its
|
|
2436
|
+
// own message, so only CLI-raised errors are narrated here.
|
|
2437
|
+
export function reportCliFailure(err, write = (line) => process.stderr.write(line)) {
|
|
2438
|
+
const code = exitCodeForError(err);
|
|
2439
|
+
if (!isCommanderError(err)) {
|
|
2440
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2441
|
+
write(`dharta: ${msg}${retryAdvice(err)}\n`);
|
|
2442
|
+
}
|
|
2443
|
+
return code;
|
|
2444
|
+
}
|
|
2445
|
+
// A rate-limited response carries how long to wait in `Retry-After`, and the
|
|
2446
|
+
// server's own message never repeats it. Without this the user is told they
|
|
2447
|
+
// were throttled and left to guess for how long.
|
|
2448
|
+
function retryAdvice(err) {
|
|
2449
|
+
const seconds = err?.retryAfterSeconds;
|
|
2450
|
+
if (typeof seconds !== "number" || !Number.isFinite(seconds) || seconds < 0)
|
|
2451
|
+
return "";
|
|
2452
|
+
return ` Retry after ${seconds} seconds.`;
|
|
2453
|
+
}
|
|
1748
2454
|
function allCommands(root) {
|
|
1749
2455
|
const out = [];
|
|
1750
2456
|
const visit = (cmd) => {
|
|
@@ -1761,8 +2467,11 @@ function hidesJsonHelp(cmd) {
|
|
|
1761
2467
|
"dharta auth",
|
|
1762
2468
|
"dharta analytics",
|
|
1763
2469
|
"dharta keys",
|
|
1764
|
-
"dharta
|
|
2470
|
+
"dharta models",
|
|
2471
|
+
"dharta models auth",
|
|
2472
|
+
"dharta org",
|
|
1765
2473
|
"dharta members",
|
|
2474
|
+
"dharta repos",
|
|
1766
2475
|
"dharta embed-keys",
|
|
1767
2476
|
"dharta caps",
|
|
1768
2477
|
"dharta appearance",
|
|
@@ -1771,6 +2480,7 @@ function hidesJsonHelp(cmd) {
|
|
|
1771
2480
|
"dharta webhooks",
|
|
1772
2481
|
"dharta env",
|
|
1773
2482
|
"dharta agent",
|
|
2483
|
+
"dharta genui",
|
|
1774
2484
|
"dharta git-credential",
|
|
1775
2485
|
"dharta dev",
|
|
1776
2486
|
"dharta logs",
|
|
@@ -1800,8 +2510,11 @@ const HELP_ONLY_COMMAND_PATHS = new Set([
|
|
|
1800
2510
|
"dharta auth",
|
|
1801
2511
|
"dharta analytics",
|
|
1802
2512
|
"dharta keys",
|
|
1803
|
-
"dharta
|
|
2513
|
+
"dharta models",
|
|
2514
|
+
"dharta models auth",
|
|
2515
|
+
"dharta org",
|
|
1804
2516
|
"dharta members",
|
|
2517
|
+
"dharta repos",
|
|
1805
2518
|
"dharta embed-keys",
|
|
1806
2519
|
"dharta caps",
|
|
1807
2520
|
"dharta caps budget",
|
|
@@ -1811,6 +2524,7 @@ const HELP_ONLY_COMMAND_PATHS = new Set([
|
|
|
1811
2524
|
"dharta webhooks",
|
|
1812
2525
|
"dharta env",
|
|
1813
2526
|
"dharta agent",
|
|
2527
|
+
"dharta genui",
|
|
1814
2528
|
]);
|
|
1815
2529
|
function rejectUnknownTopLevelCommand(program, argv, options) {
|
|
1816
2530
|
const args = argv ? [...argv].slice(options?.from === "user" ? 0 : 2) : process.argv.slice(2);
|
|
@@ -1830,8 +2544,7 @@ function rejectUnknownTopLevelCommand(program, argv, options) {
|
|
|
1830
2544
|
const path = commandPath(cursor);
|
|
1831
2545
|
if (!HELP_ONLY_COMMAND_PATHS.has(path))
|
|
1832
2546
|
return;
|
|
1833
|
-
const
|
|
1834
|
-
const child = visible.find((cmd) => cmd.name() === token || cmd.aliases().includes(token));
|
|
2547
|
+
const child = visibleSubcommands(cursor).find((cmd) => cmd.name() === token || cmd.aliases().includes(token));
|
|
1835
2548
|
if (child) {
|
|
1836
2549
|
cursor = child;
|
|
1837
2550
|
continue;
|
|
@@ -1907,21 +2620,21 @@ function parseOnOff(value, name) {
|
|
|
1907
2620
|
if (["off", "false", "disabled", "disable", "pause", "paused"].includes(normalized))
|
|
1908
2621
|
return false;
|
|
1909
2622
|
const suggestion = closestChoice(normalized, ["on", "off", "enabled", "disabled", "true", "false"]);
|
|
1910
|
-
throw new
|
|
2623
|
+
throw new CliUsageError(`${name} must be on/off, enabled/disabled, or true/false.` +
|
|
1911
2624
|
(suggestion ? ` Did you mean ${suggestion}?` : ""));
|
|
1912
2625
|
}
|
|
1913
2626
|
export async function readStdin() {
|
|
1914
2627
|
if (process.stdin.isTTY) {
|
|
1915
2628
|
// Reading a TTY would block silently until Ctrl-D — fail with the
|
|
1916
2629
|
// usage instead (gh parity: --with-token requires piped input).
|
|
1917
|
-
throw new
|
|
2630
|
+
throw new CliUsageError("No piped input. Usage: echo $DHARTA_API_KEY | dharta login --with-token");
|
|
1918
2631
|
}
|
|
1919
2632
|
const chunks = [];
|
|
1920
2633
|
for await (const chunk of process.stdin)
|
|
1921
2634
|
chunks.push(Buffer.from(chunk));
|
|
1922
2635
|
const token = Buffer.concat(chunks).toString("utf8").trim();
|
|
1923
2636
|
if (!token) {
|
|
1924
|
-
throw new
|
|
2637
|
+
throw new CliUsageError("No token on stdin. Usage: echo $DHARTA_API_KEY | dharta login --with-token");
|
|
1925
2638
|
}
|
|
1926
2639
|
return token;
|
|
1927
2640
|
}
|
|
@@ -1931,25 +2644,25 @@ function parseVersion(input) {
|
|
|
1931
2644
|
return parseReleaseVersion(input, "version");
|
|
1932
2645
|
}
|
|
1933
2646
|
catch {
|
|
1934
|
-
throw new
|
|
2647
|
+
throw new CliUsageError(`Invalid version: ${input.trim()}. Use e.g. v3 or 3.`);
|
|
1935
2648
|
}
|
|
1936
2649
|
}
|
|
1937
2650
|
function parseRollbackTarget(input) {
|
|
1938
2651
|
if (input === undefined) {
|
|
1939
|
-
throw new
|
|
2652
|
+
throw new CliUsageError("Pass --to <version>. Usage: dharta rollback [slug] --to v3");
|
|
1940
2653
|
}
|
|
1941
2654
|
return parseVersion(input);
|
|
1942
2655
|
}
|
|
1943
2656
|
function parsePort(input) {
|
|
1944
2657
|
const normalized = input.trim();
|
|
1945
2658
|
if (!normalized)
|
|
1946
|
-
throw new
|
|
2659
|
+
throw new CliUsageError("--port cannot be blank.");
|
|
1947
2660
|
if (!/^[1-9]\d*$/.test(normalized)) {
|
|
1948
|
-
throw new
|
|
2661
|
+
throw new CliUsageError(`--port must be an integer between 1 and 65535.`);
|
|
1949
2662
|
}
|
|
1950
2663
|
const port = Number(normalized);
|
|
1951
2664
|
if (port > 65535) {
|
|
1952
|
-
throw new
|
|
2665
|
+
throw new CliUsageError(`--port must be an integer between 1 and 65535.`);
|
|
1953
2666
|
}
|
|
1954
2667
|
return port;
|
|
1955
2668
|
}
|
|
@@ -1970,9 +2683,7 @@ const invokedAsBin = (() => {
|
|
|
1970
2683
|
})();
|
|
1971
2684
|
if (invokedAsBin) {
|
|
1972
2685
|
main(process.argv).catch((err) => {
|
|
1973
|
-
|
|
1974
|
-
process.stderr.write(`dharta: ${msg}\n`);
|
|
1975
|
-
process.exit(1);
|
|
2686
|
+
process.exit(reportCliFailure(err));
|
|
1976
2687
|
});
|
|
1977
2688
|
}
|
|
1978
2689
|
//# sourceMappingURL=cli.js.map
|