@constal/cli 1.1.0 → 1.2.0

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/publish/cli.mjs +5 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constal/cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Task-oriented command line client for the Constal Platform API",
5
5
  "keywords": [
6
6
  "constal",
package/publish/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{createHash as dt,randomUUID as lt}from"node:crypto";import{readFile as pt,writeFile as ut}from"node:fs/promises";import{stdin as mt,stdout as ft,stderr as ht}from"node:process";var l=(e,n,t,s={})=>({name:e,value:n,description:t,...s}),a=(e,n,t={})=>({name:e,description:n,...t}),W=Object.freeze([l("help",null,"Show command help."),l("version",null,"Show the CLI version."),l("origin","URL","Override the configured Platform API origin."),l("namespace","NAME","Override the configured namespace."),l("tenant","NAME","Restrict authentication to this tenant."),l("output","FORMAT","Render table, json, or jsonl output.",{choices:["table","json","jsonl"]})]),u=l("body","JSON|@FILE|@-","Read the JSON request body inline, from a file, or from stdin."),Ae=l("body","SOURCE","Read protected setup JSON from @FILE or @-."),se=l("idempotency-key","KEY","Use a caller-stable idempotency key."),E=l("event-id","ID","Use a caller-stable idempotency event identifier."),Y=l("reason","TEXT","Record an optional operator reason."),S=l("after","CURSOR","Continue after a returned cursor."),T=l("limit","COUNT","Bound the number of returned records."),K=l("out","FILE","Write the binary response to a file instead of stdout."),D=l("quiet",null,"Suppress the file-write status message."),A=(e,n,t={})=>Object.freeze({path:e.split(" "),summary:n,...t}),o=(e,n,t,s,i={})=>A(e,n,{method:t,route:s,...i}),_=Object.freeze([A("auth login","Save a Constal API key using a hidden prompt, stdin, or a file.",{local:"auth.login",options:[l("token-stdin",null,"Read the API key from stdin."),l("token-file","FILE","Read the API key from a file.")],examples:[`printf '%s' "$CONSTAL_API_KEY" | constal auth login --token-stdin`]}),A("auth logout","Remove the locally stored Constal API key.",{local:"auth.logout"}),A("auth status","Check whether the current credentials can read the selected namespace.",{local:"auth.status"}),A("context show","Show the effective origin, tenant restriction, namespace, and credential source.",{local:"context.show"}),A("context use","Persist the default origin, tenant restriction, or namespace.",{local:"context.use",options:[l("origin","URL","Set the Platform API origin."),l("namespace","NAME","Set the default namespace."),l("tenant","NAME","Set the tenant restriction."),l("clear-tenant",null,"Remove the tenant restriction.")],examples:["constal context use --namespace production","constal context use --tenant acme"]}),A("deploy","Deploy an existing Constal, LangGraph, or Mastra project without changing its source.",{local:"deploy.project",route:"/v1/deployments",positionals:[a("source","Project directory, deployment archive, or immutable Git URL.",{optional:!0})],query:[["rollout","rollout"],["fraction","fraction"],["tags","tags"]],options:[l("idempotency-key","KEY","Override the content-derived deployment key."),l("rollout","STRATEGY","Activate immediately or begin a canary.",{choices:["immediate","canary"]}),l("fraction","RATE","Fraction of eligible new Sessions assigned to the candidate."),l("tags","JSON","Optional exact-match tag selector for canary eligibility."),l("mastra-storage","MODE","Substitute Constal storage or retain the project's configured Mastra store.",{choices:["constal","project"]}),l("bind","NAME=CRN","Bind a framework transport or integration to an existing Resource.",{repeatable:!0}),l("wait",null,"Wait for the authoritative build result; use --no-wait to return after upload."),l("timeout","SECONDS","Maximum time to wait for the build.")],examples:["constal deploy","constal deploy .","constal deploy https://github.com/example/agent#0123456789abcdef0123456789abcdef01234567"]}),o("deployments create","Upload an immutable executable ZIP or tar.gz package.","POST","/v1/deployments",{positionals:[a("archive","Path to the ZIP or tar.gz package.")],bodyKind:"archive",query:[["rollout","rollout"],["fraction","fraction"],["tags","tags"]],options:[l("idempotency-key","KEY","Override the content-derived deployment key."),l("rollout","STRATEGY","Activate immediately or begin a canary.",{choices:["immediate","canary"]}),l("fraction","RATE","Fraction of eligible new Sessions assigned to the candidate."),l("tags","JSON","Optional exact-match tag selector for canary eligibility."),l("mastra-storage","MODE","Substitute Constal storage or retain the project's configured Mastra store.",{choices:["constal","project"]}),l("bind","NAME=CRN","Bind a framework transport or integration to an existing Resource.",{repeatable:!0})],examples:["constal deployments create support-agent.zip"]}),o("deployments get","Read deployment build and publication state.","GET","/v1/deployments/{deployment}",{positionals:[a("deployment","Deployment UUID.")]}),o("agents list","List deployed Agents in the namespace.","GET","/v1/namespaces/{namespace}/agents"),o("agents get","Read one deployed Agent.","GET","/v1/namespaces/{namespace}/agents/{agent}",{positionals:[a("agent","Agent id.")]}),o("agents rollout get","Read the active or most recent canary rollout.","GET","/v1/namespaces/{namespace}/agents/{agent}/rollout",{positionals:[a("agent","Agent id.")]}),...["promote","rollback"].map(e=>o(`agents rollout ${e}`,`${e==="promote"?"Promote":"Roll back"} one exact canary deployment.`,"POST",`/v1/namespaces/{namespace}/agents/{agent}/rollout/${e}`,{positionals:[a("agent","Agent id.")],bodyKind:"rollout-control",eventId:!0,options:[l("deployment","REVISION","Exact canary deployment revision.",{required:!0}),l("reason","TEXT","Record why this rollout decision was made.",{required:!0}),E]})),o("runs start","Start an Agent Run in a stable session.","POST","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/events",{positionals:[a("agent","Agent id."),a("session","Stable session id.")],bodyKind:"run-start",eventId:!0,options:[l("data","JSON|@FILE|@-","Agent input JSON."),l("deliver","MODE","Queue work or drive it live.",{choices:["queue","live"]}),l("tags","JSON|@FILE|@-","Attach bounded tags used by policy-governed live sampling."),E],examples:["constal runs start support customer-42 --data @request.json --deliver live"]}),o("runs session","Read bounded authoritative session state.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}",{positionals:[a("agent","Agent id."),a("session","Session id.")],query:[["limit","limit"]],options:[T]}),o("runs events","Page accepted session events and ledger history.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/events",{positionals:[a("agent","Agent id."),a("session","Session id.")],query:[["after","after"],["limit","limit"]],options:[S,T]}),o("runs workflow","Read the authoritative current workflow view.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/workflow",{positionals:[a("agent","Agent id."),a("session","Session id.")]}),o("runs get","Read one authoritative Run.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")]}),o("runs detail","Read bounded Run, fact, wait, steer, and journal detail.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/detail",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],query:[["limit","journalLimit"]],options:[T]}),o("runs journal","Read the cryptographically rooted Run journal.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/journal",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],query:[["after","after"],["limit","limit"]],options:[S,T]}),o("runs journal-window","Page an operator-oriented Run journal window.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/journal-window",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],query:[["after","after"],["before","before"],["limit","limit"]],options:[S,l("before","CURSOR","Read before a returned cursor."),T]}),o("runs waits","List open durable waits for a session.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/waits",{positionals:[a("agent","Agent id."),a("session","Session id.")]}),o("runs resolve","Resolve one durable wait with a schema-checked value.","POST","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/waits/{promise}/resolve",{positionals:[a("agent","Agent id."),a("session","Session id."),a("promise","Wait promise id.")],bodyKind:"wait-resolve",eventId:!0,options:[l("value","JSON|@FILE|@-","Resolution value."),E]}),o("runs steer","Append authenticated guidance to a session.","POST","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/steers",{positionals:[a("agent","Agent id."),a("session","Session id.")],bodyKind:"steer",eventId:!0,options:[l("text","TEXT","Guidance text.",{required:!0}),l("data","JSON|@FILE|@-","Optional structured guidance."),E]}),o("runs stream","Stream committed Run frames over Server-Sent Events.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/stream",{positionals:[a("agent","Agent id."),a("session","Session id.")],query:[["run","runId"]],options:[l("run","RUN","Run id to stream.",{required:!0})],stream:!0}),o("runs delete-session","Delete a session asynchronously and preserve a bounded tombstone.","DELETE","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}",{positionals:[a("agent","Agent id."),a("session","Session id.")],bodyKind:"json",eventId:!0,options:[E]}),o("runs deletion","Read asynchronous session-deletion progress.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/deletion",{positionals:[a("agent","Agent id."),a("session","Session id.")]}),...["pause","resume","cancel"].map(e=>o(`runs ${e}`,`${e[0].toUpperCase()}${e.slice(1)} one exact Run.`,"POST",`/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/${e}`,{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],bodyKind:"json",eventId:!0,options:[u,E]})),o("runs interrupt","Interrupt a Run at a safe point or abort active work.","POST","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/interrupt",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],bodyKind:"interrupt",eventId:!0,options:[l("mode","MODE","Use safe-point or abort.",{required:!0,choices:["safe-point","abort"]}),u,E]}),...["policy","rebind","truncate","branch"].map(e=>o(`runs ${e}`,`Apply an idempotent ${e} control to one Run.`,"POST",`/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/${e}`,{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],bodyKind:"json",eventId:!0,options:[u,E]})),o("resources list","List configured Resources, optionally by kind.","GET","/v1/namespaces/{namespace}/resources",{query:[["kind","kind"],["after","after"],["limit","limit"]],options:[l("kind","KIND","Filter by Resource kind."),S,T]}),o("resources create","Create a configured Resource from a JSON definition.","POST","/v1/namespaces/{namespace}/resources",{bodyKind:"required-json",options:[u]}),...["get","delete"].map(e=>o(`resources ${e}`,`${e==="get"?"Read":"Delete"} one tenant-managed Resource.`,e==="get"?"GET":"DELETE","/v1/namespaces/{namespace}/resources/{kind}/{id}",{positionals:[a("kind","Resource kind."),a("id","Resource id.")]})),o("resources control","Read one Resource control head.","GET","/v1/namespaces/{namespace}/resources/{kind}/{id}/control",{positionals:[a("kind","Resource kind."),a("id","Resource id.")]}),...["enable","disable"].map(e=>o(`resources ${e}`,`${e[0].toUpperCase()}${e.slice(1)} a tenant-managed Resource.`,"POST",`/v1/namespaces/{namespace}/resources/{kind}/{id}/${e}`,{positionals:[a("kind","Resource kind."),a("id","Resource id.")],bodyKind:"reason",eventId:!0,options:[E,Y]})),o("bindings list","List scoped Resource and Credential assignments.","GET","/v1/namespaces/{namespace}/bindings",{query:[["after","after"],["limit","limit"]],options:[S,T]}),o("bindings create","Create a scoped assignment from a JSON definition.","POST","/v1/namespaces/{namespace}/bindings",{bodyKind:"required-json",eventId:!0,options:[u,E]}),o("bindings get","Read one scoped assignment.","GET","/v1/namespaces/{namespace}/bindings/{binding}",{positionals:[a("binding","Binding id.")]}),o("bindings delete","Delete one scoped assignment idempotently.","DELETE","/v1/namespaces/{namespace}/bindings/{binding}",{positionals:[a("binding","Binding id.")],bodyKind:"json",eventId:!0,options:[E]}),o("bindings promote","Promote a binding when its current revision still matches.","POST","/v1/namespaces/{namespace}/bindings/{binding}/promote",{positionals:[a("binding","Binding id.")],bodyKind:"required-json",eventId:!0,options:[u,E]}),...["enable","disable","revoke"].map(e=>o(`bindings ${e}`,`${e[0].toUpperCase()}${e.slice(1)} one scoped assignment.`,"POST",`/v1/namespaces/{namespace}/bindings/{binding}/${e}`,{positionals:[a("binding","Binding id.")],bodyKind:"reason",eventId:!0,options:[E,Y]})),o("credentials providers catalog","List Credential Provider packages visible to the tenant.","GET","/v1/namespaces/{namespace}/credential-provider-catalog"),o("credentials providers list","List installed Credential Providers.","GET","/v1/namespaces/{namespace}/credential-providers"),o("credentials providers get","Read one installed Credential Provider.","GET","/v1/namespaces/{namespace}/credential-providers/{provider}",{positionals:[a("provider","Provider id.")]}),o("credentials providers install","Install a catalog Credential Provider package.","POST","/v1/namespaces/{namespace}/credential-providers/install",{bodyKind:"protected-json",options:[Ae],examples:["constal credentials providers install --body @provider-setup.json"]}),o("credentials list","List Credentials without returning material.","GET","/v1/namespaces/{namespace}/credentials"),o("credentials get","Read authoritative Credential metadata.","GET","/v1/namespaces/{namespace}/credentials/{credential}",{positionals:[a("credential","Credential id.")]}),o("credentials create","Create, mint, or begin authorization for a Credential.","POST","/v1/namespaces/{namespace}/credentials",{positionals:[a("credential","New Credential id.")],bodyKind:"credential-create",options:[l("provider","CRN","Installed Credential Provider CRN.",{required:!0}),l("configuration","JSON|@FILE","Provider-defined non-secret configuration."),l("material-file","FILE","Read imported secret material from a file."),l("material-stdin",null,"Read imported secret material from stdin."),l("policies","JSON|@FILE","Optional Policy CRN array.")]}),o("credentials version","Add imported material as a scheduled Credential version.","POST","/v1/namespaces/{namespace}/credentials/{credential}/versions",{positionals:[a("credential","Credential id.")],bodyKind:"credential-version",options:[l("material-file","FILE","Read secret material from a file."),l("material-stdin",null,"Read secret material from stdin.")]}),...["activate","rotate","authorize","revoke"].map(e=>o(`credentials ${e}`,`${e[0].toUpperCase()}${e.slice(1)} a Credential lifecycle operation.`,"POST",`/v1/namespaces/{namespace}/credentials/{credential}/${e}`,{positionals:[a("credential","Credential id.")],bodyKind:"json",options:[u]})),...["consumers","uses","events"].map(e=>o(`credentials ${e}`,`List bounded Credential ${e}.`,"GET",`/v1/namespaces/{namespace}/credentials/{credential}/${e}`,{positionals:[a("credential","Credential id.")],query:e==="consumers"?[["after","after"],["limit","limit"]]:[["after","after"]],options:e==="consumers"?[S,T]:[S]})),o("channels list","List deployed Channels.","GET","/v1/namespaces/{namespace}/channels"),o("channels get","Read one deployed Channel.","GET","/v1/namespaces/{namespace}/channels/{channel}",{positionals:[a("channel","Channel id.")]}),o("channels send","Send one outbound Channel message.","POST","/v1/namespaces/{namespace}/channels/{channel}/messages",{positionals:[a("channel","Channel id.")],bodyKind:"required-json",options:[u]}),o("channels message","Read one outbound delivery receipt.","GET","/v1/namespaces/{namespace}/channels/{channel}/messages/{message}",{positionals:[a("channel","Channel id."),a("message","Message id.")]}),o("channels events","Read bounded Channel events.","GET","/v1/namespaces/{namespace}/channels/{channel}/events",{positionals:[a("channel","Channel id.")],query:[["after","after"],["limit","limit"]],options:[S,T]}),o("channels alarm","Schedule a Channel alarm.","POST","/v1/namespaces/{namespace}/channels/{channel}/alarms",{positionals:[a("channel","Channel id.")],bodyKind:"required-json",options:[u]}),o("channels alarm-get","Read one Channel alarm.","GET","/v1/namespaces/{namespace}/channels/{channel}/alarms/{alarm}",{positionals:[a("channel","Channel id."),a("alarm","Alarm id.")]}),o("channels alarm-cancel","Cancel one Channel alarm.","DELETE","/v1/namespaces/{namespace}/channels/{channel}/alarms/{alarm}",{positionals:[a("channel","Channel id."),a("alarm","Alarm id.")]}),o("policies evaluate","Evaluate a deployed Policy against a normalized test input.","POST","/v1/namespaces/{namespace}/policies/{policy}/evaluate",{positionals:[a("policy","Policy id.")],bodyKind:"required-json",options:[u]}),o("analytics summary","Read a bounded recent analytics summary.","GET","/v1/namespaces/{namespace}/analytics/summary"),...["live","dashboard","query","export"].map(e=>o(`analytics ${e}`,`${e==="export"?"Create":"Query"} ${e} analytics data.`,"POST",`/v1/namespaces/{namespace}/analytics/${e==="export"?"exports":e}`,{bodyKind:"required-json",options:[u]})),o("analytics export-get","Download one namespace-owned analytics export.","GET","/v1/namespaces/{namespace}/analytics/exports/{ref}",{positionals:[a("ref","Export artifact hash.")],binary:!0,options:[K,D]}),o("evals datasets list","List immutable Dataset Resources.","GET","/v1/namespaces/{namespace}/resources",{queryValues:{kind:"dataset"}}),o("evals datasets create","Create or idempotently initialize a Dataset draft.","POST","/v1/namespaces/{namespace}/evals/datasets/{dataset}/draft",{positionals:[a("dataset","Dataset id.")],bodyKind:"required-json",options:[u]}),o("evals datasets draft","Read a Dataset draft head.","GET","/v1/namespaces/{namespace}/evals/datasets/{dataset}/draft",{positionals:[a("dataset","Dataset id.")]}),o("evals datasets cases","Page cases in a Dataset draft.","GET","/v1/namespaces/{namespace}/evals/datasets/{dataset}/cases",{positionals:[a("dataset","Dataset id.")],query:[["after","after"],["limit","limit"]],options:[S,T]}),o("evals datasets add-case","Create or replace one caller-identified Dataset case.","POST","/v1/namespaces/{namespace}/evals/datasets/{dataset}/cases",{positionals:[a("dataset","Dataset id.")],bodyKind:"required-json",options:[u]}),o("evals datasets delete-case","Delete one case from a Dataset draft.","DELETE","/v1/namespaces/{namespace}/evals/datasets/{dataset}/cases/{case}",{positionals:[a("dataset","Dataset id."),a("case","Case id.")]}),o("evals datasets capture","Capture a recorded Agent interaction into a Dataset draft.","POST","/v1/namespaces/{namespace}/evals/datasets/{dataset}/capture",{positionals:[a("dataset","Dataset id.")],bodyKind:"required-json",options:[u]}),o("evals datasets publish","Publish the current Dataset draft as an immutable version.","POST","/v1/namespaces/{namespace}/evals/datasets/{dataset}/publish",{positionals:[a("dataset","Dataset id.")],bodyKind:"required-json",options:[u]}),o("evals scores start","Score a pinned Subject asynchronously and append its verdict to the judged Session.","POST","/v1/namespaces/{namespace}/evals/scores",{bodyKind:"required-json",options:[u,se]}),o("evals scores get","Read one durable scoring job.","GET","/v1/namespaces/{namespace}/evals/scores/{score}",{positionals:[a("score","Score job id.")]}),o("evals scores cancel","Cancel one durable scoring job.","POST","/v1/namespaces/{namespace}/evals/scores/{score}/cancel",{positionals:[a("score","Score job id.")],bodyKind:"optional-json",options:[u]}),o("evals labels request","Open a durable, schema-checked human labeling wait.","POST","/v1/namespaces/{namespace}/evals/labels",{bodyKind:"required-json",options:[u,se]}),o("evals scorers list","List versioned Scorer Resources.","GET","/v1/namespaces/{namespace}/resources",{queryValues:{kind:"scorer"}}),o("evals scorers create","Create a versioned code, Judge Agent, or human-review Scorer.","POST","/v1/namespaces/{namespace}/evals/scorers",{bodyKind:"required-json",options:[u]}),o("evals scorers get","Read one Scorer Resource.","GET","/v1/namespaces/{namespace}/resources/scorer/{scorer}",{positionals:[a("scorer","Scorer id.")]}),o("evals suites list","Page evaluation suites by most recent activity.","GET","/v1/namespaces/{namespace}/evals/suites",{query:[["after","after"],["limit","limit"]],options:[S,T]}),o("evals suites start","Run a fresh suite over an immutable Dataset.","POST","/v1/namespaces/{namespace}/evals/suites",{bodyKind:"required-json",options:[u]}),o("evals suites get","Read authoritative suite progress and results.","GET","/v1/namespaces/{namespace}/evals/suites/{suite}",{positionals:[a("suite","Suite id.")]}),o("evals suites cancel","Cancel a running evaluation suite.","POST","/v1/namespaces/{namespace}/evals/suites/{suite}/cancel",{positionals:[a("suite","Suite id.")],bodyKind:"json",options:[u]}),o("evals compare","Compare paired suite and baseline verdicts.","POST","/v1/namespaces/{namespace}/evals/compare",{bodyKind:"required-json",options:[u]}),o("evals baseline","Set an Agent's evaluation baseline.","POST","/v1/namespaces/{namespace}/evals/baseline",{bodyKind:"required-json",options:[u]}),o("evals policy get","Read the namespace eval door policy pinned at Run admission.","GET","/v1/namespaces/{namespace}/evals/policy"),o("evals policy set","Atomically set sampling rates, Scorers, and eval budget ceilings.","PUT","/v1/namespaces/{namespace}/evals/policy",{bodyKind:"required-json",options:[u]}),o("evals samples list","Page asynchronous live-traffic scoring dispatches.","GET","/v1/namespaces/{namespace}/evals/samples",{query:[["before","before"],["limit","limit"]],options:[l("before","TIMESTAMP","Read samples created before this millisecond timestamp."),T]}),o("evals schedules list","List continuous evaluation schedules.","GET","/v1/namespaces/{namespace}/evals/schedules"),o("evals schedules get","Read one continuous evaluation schedule.","GET","/v1/namespaces/{namespace}/evals/schedules/{schedule}",{positionals:[a("schedule","Schedule id.")]}),o("evals schedules apply","Create or atomically update a continuous evaluation schedule.","PUT","/v1/namespaces/{namespace}/evals/schedules/{schedule}",{positionals:[a("schedule","Schedule id.")],bodyKind:"required-json",options:[u]}),o("evals schedules delete","Delete one exact continuous evaluation schedule revision.","DELETE","/v1/namespaces/{namespace}/evals/schedules/{schedule}",{positionals:[a("schedule","Schedule id.")],bodyKind:"schedule-delete",options:[l("expected-hash","HASH","Current schedule hash.",{required:!0})]}),o("evals schedules run","Run a scheduled Suite now without changing its cadence.","POST","/v1/namespaces/{namespace}/evals/schedules/{schedule}/run",{positionals:[a("schedule","Schedule id.")],bodyKind:"json",eventId:!0,options:[E]}),o("evals training providers","List installed Training Providers and checkpoint capabilities.","GET","/v1/namespaces/{namespace}/evals/training-providers"),o("evals training models","List models and pinned prices advertised by one Training Provider.","GET","/v1/namespaces/{namespace}/evals/training-models",{query:[["provider","provider"],["hash","hash"]],options:[l("provider","CRN","Training Provider Resource CRN."),l("hash","HASH","Exact Training Provider Resource hash.")]}),o("evals training list","Page fine-tuning and reinforcement-learning jobs.","GET","/v1/namespaces/{namespace}/evals/training-jobs",{query:[["after","after"],["limit","limit"]],options:[S,T]}),o("evals training start","Start a durable metered SFT or RL job.","POST","/v1/namespaces/{namespace}/evals/training-jobs",{bodyKind:"required-json",options:[u]}),o("evals training get","Read authoritative training progress, usage, and results.","GET","/v1/namespaces/{namespace}/evals/training-jobs/{job}",{positionals:[a("job","Training job id.")]}),o("evals training cancel","Cancel a running training job.","POST","/v1/namespaces/{namespace}/evals/training-jobs/{job}/cancel",{positionals:[a("job","Training job id.")],bodyKind:"json",options:[u]}),o("evals training checkpoint-gateways","List exact Gateway revisions compatible with one durable checkpoint.","GET","/v1/namespaces/{namespace}/evals/training-jobs/{job}/checkpoint-gateways",{positionals:[a("job","Succeeded Training Job id.")],query:[["step","step"],["ref","ref"]],options:[l("step","COUNT","Exact checkpoint step."),l("ref","HASH","Exact checkpoint Artifact hash.")]}),o("evals training create-model","Import a checkpoint through a compatible Gateway and create a Model.","POST","/v1/namespaces/{namespace}/evals/training-jobs/{job}/models",{positionals:[a("job","Succeeded Training Job id.")],bodyKind:"required-json",options:[u]}),o("memory stores list","List configured Memory Stores.","GET","/v1/namespaces/{namespace}/resources",{queryValues:{kind:"memory-store"}}),o("memory stores create","Create a Memory Store Resource.","POST","/v1/namespaces/{namespace}/resources",{bodyKind:"resource-kind",resourceKind:"memory-store",options:[u]}),...["get","delete"].map(e=>o(`memory stores ${e}`,`${e==="get"?"Read":"Delete"} one Memory Store.`,e==="get"?"GET":"DELETE","/v1/namespaces/{namespace}/resources/memory-store/{id}",{positionals:[a("id","Memory Store id.")]})),o("memory list","List configured Memory Resources.","GET","/v1/namespaces/{namespace}/resources",{queryValues:{kind:"memory"}}),o("memory create","Create a Memory Resource.","POST","/v1/namespaces/{namespace}/resources",{bodyKind:"resource-kind",resourceKind:"memory",options:[u]}),...["get","delete"].map(e=>o(`memory ${e}`,`${e==="get"?"Read":"Delete"} one Memory Resource.`,e==="get"?"GET":"DELETE","/v1/namespaces/{namespace}/resources/memory/{id}",{positionals:[a("id","Memory id.")]})),o("customers list","List downstream customers.","GET","/v1/customers"),o("customers get","Read one downstream customer.","GET","/v1/customers/{customer}",{positionals:[a("customer","Customer id.")]}),o("customers put","Create or update a downstream customer.","PUT","/v1/customers/{customer}",{positionals:[a("customer","Customer id.")],bodyKind:"required-json",eventId:!0,options:[u,E]}),...["enable","disable"].map(e=>o(`customers ${e}`,`${e[0].toUpperCase()}${e.slice(1)} a downstream customer.`,"POST",`/v1/customers/{customer}/${e}`,{positionals:[a("customer","Customer id.")],bodyKind:"reason",eventId:!0,options:[E,Y]})),...[["map","Map an external identity to a downstream customer.","PUT","identity-mappings"],["unmap","Remove an external identity mapping from a downstream customer.","DELETE","identity-mappings"],["bind-policy","Bind a Policy to a downstream customer.","PUT","policy-bindings"],["unbind-policy","Remove a Policy binding from a downstream customer.","DELETE","policy-bindings"]].map(([e,n,t,s])=>o(`customers ${e}`,n,t,`/v1/customers/{customer}/${s}/{binding}`,{positionals:[a("customer","Customer id."),a("binding","Mapping or binding id.")],bodyKind:"required-json",eventId:!0,options:[u,E]})),o("artifacts get","Download an authorized content-addressed artifact.","GET","/v1/artifacts/{ref}",{positionals:[a("ref","Artifact hash.")],binary:!0,options:[K,D]}),o("exports get","Download a redacted durable export.","GET","/v1/exports/{ref}",{positionals:[a("ref","Export hash.")],binary:!0,options:[K,D]}),o("anchors get","Download an authorized customer audit anchor.","GET","/v1/anchors/{ref}",{positionals:[a("ref","Anchor hash.")],binary:!0,options:[K,D]}),o("stages get","Inspect one map/reduce stage.","GET","/v1/stages/{stage}",{positionals:[a("stage","Stage hash.")]}),o("stages recover","Request authorized stage recovery.","POST","/v1/stages/{stage}/recover",{positionals:[a("stage","Stage hash.")],bodyKind:"json",options:[u]}),o("tables get","Read a table branch head and state.","GET","/v1/namespaces/{namespace}/tables/{table}",{positionals:[a("table","Table id.")],query:[["branch","branch"]],options:[l("branch","NAME","Table branch; defaults to main.")]}),o("tables export-get","Read an exact table catalog commit, export, or intent.","GET","/v1/namespaces/{namespace}/table-exports/{table}/{branch}/{sequence}/{hash}",{positionals:[a("table","Table id."),a("branch","Branch name."),a("sequence","Commit sequence."),a("hash","Commit hash.")],binary:!0,options:[K,D]})]);function G(e){return e.path.join(" ")}function Ce(e=_){let n=new Set;for(let t of e){let s=G(t);if(n.has(s))throw new TypeError(`duplicate CLI command ${s}`);if(n.add(s),!t.summary||!t.local&&(!t.method||!t.route))throw new TypeError(`invalid CLI command ${s}`);let i=t.positionals??[];if(new Set(i.map(c=>c.name)).size!==i.length)throw new TypeError(`duplicate positional in ${s}`);let r=t.options??[];if(new Set(r.map(c=>c.name)).size!==r.length)throw new TypeError(`duplicate option in ${s}`);for(let c of t.route?.matchAll(/\{([^}]+)\}/gu)??[])if(c[1]!=="namespace"&&!i.some(d=>d.name===c[1]))throw new TypeError(`unknown route placeholder ${c[1]} in ${s}`)}return e}Ce();import{randomUUID as Pe}from"node:crypto";import{chmod as ae,mkdir as xe,readFile as Ne,rename as Ie,unlink as qe,writeFile as Le}from"node:fs/promises";import{homedir as Ke}from"node:os";import{dirname as De,join as z}from"node:path";var B="https://platform.constal.ai",Ge=/^[a-z0-9][a-z0-9._-]{0,127}$/u;function Me(e=process.env){return e.CONSTAL_CONFIG_DIR||z(e.XDG_CONFIG_HOME||z(Ke(),".config"),"constal")}function J(e=process.env){let n=Me(e);return{root:n,context:z(n,"config.json"),credentials:z(n,"credentials.json")}}async function V(e){try{let n=JSON.parse(await Ne(e,"utf8"));return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}catch(n){if(n?.code==="ENOENT")return{};throw new TypeError(`Cannot read Constal configuration at ${e}: ${n instanceof Error?n.message:String(n)}`)}}async function oe(e,n,t){await xe(De(e),{recursive:!0,mode:448});let s=`${e}.${process.pid}.${Pe()}.tmp`;await Le(s,`${JSON.stringify(n,null,2)}
2
+ import{createHash as dt,randomUUID as lt}from"node:crypto";import{readFile as pt,writeFile as ut}from"node:fs/promises";import{stdin as mt,stdout as ft,stderr as ht}from"node:process";var l=(e,n,t,s={})=>({name:e,value:n,description:t,...s}),a=(e,n,t={})=>({name:e,description:n,...t}),W=Object.freeze([l("help",null,"Show command help."),l("version",null,"Show the CLI version."),l("origin","URL","Override the configured Platform API origin."),l("namespace","NAME","Override the configured namespace."),l("tenant","NAME","Restrict authentication to this tenant."),l("output","FORMAT","Render table, json, or jsonl output.",{choices:["table","json","jsonl"]})]),u=l("body","JSON|@FILE|@-","Read the JSON request body inline, from a file, or from stdin."),ke=l("body","SOURCE","Read protected setup JSON from @FILE or @-."),se=l("idempotency-key","KEY","Use a caller-stable idempotency key."),E=l("event-id","ID","Use a caller-stable idempotency event identifier."),Y=l("reason","TEXT","Record an optional operator reason."),S=l("after","CURSOR","Continue after a returned cursor."),T=l("limit","COUNT","Bound the number of returned records."),K=l("out","FILE","Write the binary response to a file instead of stdout."),D=l("quiet",null,"Suppress the file-write status message."),k=(e,n,t={})=>Object.freeze({path:e.split(" "),summary:n,...t}),o=(e,n,t,s,i={})=>k(e,n,{method:t,route:s,...i}),_=Object.freeze([k("auth login","Save a Constal API key using a hidden prompt, stdin, or a file.",{local:"auth.login",options:[l("token-stdin",null,"Read the API key from stdin."),l("token-file","FILE","Read the API key from a file.")],examples:[`printf '%s' "$CONSTAL_API_KEY" | constal auth login --token-stdin`]}),k("auth logout","Remove the locally stored Constal API key.",{local:"auth.logout"}),k("auth status","Check whether the current credentials can read the selected namespace.",{local:"auth.status"}),k("context show","Show the effective origin, tenant restriction, namespace, and credential source.",{local:"context.show"}),k("context use","Persist the default origin, tenant restriction, or namespace.",{local:"context.use",options:[l("origin","URL","Set the Platform API origin."),l("namespace","NAME","Set the default namespace."),l("tenant","NAME","Set the tenant restriction."),l("clear-tenant",null,"Remove the tenant restriction.")],examples:["constal context use --namespace production","constal context use --tenant acme"]}),k("deploy","Deploy an existing Constal, LangGraph, Mastra, OpenAI SDK, or Claude Managed Agents project unchanged.",{local:"deploy.project",route:"/v1/deployments",positionals:[a("source","Project directory, deployment archive, or immutable Git URL.",{optional:!0})],query:[["rollout","rollout"],["fraction","fraction"],["tags","tags"]],options:[l("idempotency-key","KEY","Override the content-derived deployment key."),l("rollout","STRATEGY","Activate immediately or begin a canary.",{choices:["immediate","canary"]}),l("fraction","RATE","Fraction of eligible new Sessions assigned to the candidate."),l("tags","JSON","Optional exact-match tag selector for canary eligibility."),l("mastra-storage","MODE","Substitute Constal storage or retain the project's configured Mastra store.",{choices:["constal","project"]}),l("bind","NAME=CRN","Bind a framework transport or integration to an existing Resource.",{repeatable:!0}),l("wait",null,"Wait for the authoritative build result; use --no-wait to return after upload."),l("timeout","SECONDS","Maximum time to wait for the build.")],examples:["constal deploy","constal deploy .","constal deploy https://github.com/example/agent#0123456789abcdef0123456789abcdef01234567"]}),o("deployments create","Upload an immutable executable ZIP or tar.gz package.","POST","/v1/deployments",{positionals:[a("archive","Path to the ZIP or tar.gz package.")],bodyKind:"archive",query:[["rollout","rollout"],["fraction","fraction"],["tags","tags"]],options:[l("idempotency-key","KEY","Override the content-derived deployment key."),l("rollout","STRATEGY","Activate immediately or begin a canary.",{choices:["immediate","canary"]}),l("fraction","RATE","Fraction of eligible new Sessions assigned to the candidate."),l("tags","JSON","Optional exact-match tag selector for canary eligibility."),l("mastra-storage","MODE","Substitute Constal storage or retain the project's configured Mastra store.",{choices:["constal","project"]}),l("bind","NAME=CRN","Bind a framework transport or integration to an existing Resource.",{repeatable:!0})],examples:["constal deployments create support-agent.zip"]}),o("deployments get","Read deployment build and publication state.","GET","/v1/deployments/{deployment}",{positionals:[a("deployment","Deployment UUID.")]}),o("agents list","List deployed Agents in the namespace.","GET","/v1/namespaces/{namespace}/agents"),o("agents get","Read one deployed Agent.","GET","/v1/namespaces/{namespace}/agents/{agent}",{positionals:[a("agent","Agent id.")]}),o("agents rollout get","Read the active or most recent canary rollout.","GET","/v1/namespaces/{namespace}/agents/{agent}/rollout",{positionals:[a("agent","Agent id.")]}),...["promote","rollback"].map(e=>o(`agents rollout ${e}`,`${e==="promote"?"Promote":"Roll back"} one exact canary deployment.`,"POST",`/v1/namespaces/{namespace}/agents/{agent}/rollout/${e}`,{positionals:[a("agent","Agent id.")],bodyKind:"rollout-control",eventId:!0,options:[l("deployment","REVISION","Exact canary deployment revision.",{required:!0}),l("reason","TEXT","Record why this rollout decision was made.",{required:!0}),E]})),o("runs start","Start an Agent Run in a stable session.","POST","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/events",{positionals:[a("agent","Agent id."),a("session","Stable session id.")],bodyKind:"run-start",eventId:!0,options:[l("data","JSON|@FILE|@-","Agent input JSON."),l("deliver","MODE","Queue work or drive it live.",{choices:["queue","live"]}),l("tags","JSON|@FILE|@-","Attach bounded tags used by policy-governed live sampling."),E],examples:["constal runs start support customer-42 --data @request.json --deliver live"]}),o("runs session","Read bounded authoritative session state.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}",{positionals:[a("agent","Agent id."),a("session","Session id.")],query:[["limit","limit"]],options:[T]}),o("runs events","Page accepted session events and ledger history.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/events",{positionals:[a("agent","Agent id."),a("session","Session id.")],query:[["after","after"],["limit","limit"]],options:[S,T]}),o("runs workflow","Read the authoritative current workflow view.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/workflow",{positionals:[a("agent","Agent id."),a("session","Session id.")]}),o("runs get","Read one authoritative Run.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")]}),o("runs detail","Read bounded Run, fact, wait, steer, and journal detail.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/detail",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],query:[["limit","journalLimit"]],options:[T]}),o("runs journal","Read the cryptographically rooted Run journal.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/journal",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],query:[["after","after"],["limit","limit"]],options:[S,T]}),o("runs journal-window","Page an operator-oriented Run journal window.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/journal-window",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],query:[["after","after"],["before","before"],["limit","limit"]],options:[S,l("before","CURSOR","Read before a returned cursor."),T]}),o("runs waits","List open durable waits for a session.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/waits",{positionals:[a("agent","Agent id."),a("session","Session id.")]}),o("runs resolve","Resolve one durable wait with a schema-checked value.","POST","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/waits/{promise}/resolve",{positionals:[a("agent","Agent id."),a("session","Session id."),a("promise","Wait promise id.")],bodyKind:"wait-resolve",eventId:!0,options:[l("value","JSON|@FILE|@-","Resolution value."),E]}),o("runs steer","Append authenticated guidance to a session.","POST","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/steers",{positionals:[a("agent","Agent id."),a("session","Session id.")],bodyKind:"steer",eventId:!0,options:[l("text","TEXT","Guidance text.",{required:!0}),l("data","JSON|@FILE|@-","Optional structured guidance."),E]}),o("runs stream","Stream committed Run frames over Server-Sent Events.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/stream",{positionals:[a("agent","Agent id."),a("session","Session id.")],query:[["run","runId"]],options:[l("run","RUN","Run id to stream.",{required:!0})],stream:!0}),o("runs delete-session","Delete a session asynchronously and preserve a bounded tombstone.","DELETE","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}",{positionals:[a("agent","Agent id."),a("session","Session id.")],bodyKind:"json",eventId:!0,options:[E]}),o("runs deletion","Read asynchronous session-deletion progress.","GET","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/deletion",{positionals:[a("agent","Agent id."),a("session","Session id.")]}),...["pause","resume","cancel"].map(e=>o(`runs ${e}`,`${e[0].toUpperCase()}${e.slice(1)} one exact Run.`,"POST",`/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/${e}`,{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],bodyKind:"json",eventId:!0,options:[u,E]})),o("runs interrupt","Interrupt a Run at a safe point or abort active work.","POST","/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/interrupt",{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],bodyKind:"interrupt",eventId:!0,options:[l("mode","MODE","Use safe-point or abort.",{required:!0,choices:["safe-point","abort"]}),u,E]}),...["policy","rebind","truncate","branch"].map(e=>o(`runs ${e}`,`Apply an idempotent ${e} control to one Run.`,"POST",`/v1/namespaces/{namespace}/agents/{agent}/sessions/{session}/runs/{run}/${e}`,{positionals:[a("agent","Agent id."),a("session","Session id."),a("run","Run id.")],bodyKind:"json",eventId:!0,options:[u,E]})),o("resources list","List configured Resources, optionally by kind.","GET","/v1/namespaces/{namespace}/resources",{query:[["kind","kind"],["after","after"],["limit","limit"]],options:[l("kind","KIND","Filter by Resource kind."),S,T]}),o("resources create","Create a configured Resource from a JSON definition.","POST","/v1/namespaces/{namespace}/resources",{bodyKind:"required-json",options:[u]}),...["get","delete"].map(e=>o(`resources ${e}`,`${e==="get"?"Read":"Delete"} one tenant-managed Resource.`,e==="get"?"GET":"DELETE","/v1/namespaces/{namespace}/resources/{kind}/{id}",{positionals:[a("kind","Resource kind."),a("id","Resource id.")]})),o("resources control","Read one Resource control head.","GET","/v1/namespaces/{namespace}/resources/{kind}/{id}/control",{positionals:[a("kind","Resource kind."),a("id","Resource id.")]}),...["enable","disable"].map(e=>o(`resources ${e}`,`${e[0].toUpperCase()}${e.slice(1)} a tenant-managed Resource.`,"POST",`/v1/namespaces/{namespace}/resources/{kind}/{id}/${e}`,{positionals:[a("kind","Resource kind."),a("id","Resource id.")],bodyKind:"reason",eventId:!0,options:[E,Y]})),o("bindings list","List scoped Resource and Credential assignments.","GET","/v1/namespaces/{namespace}/bindings",{query:[["after","after"],["limit","limit"]],options:[S,T]}),o("bindings create","Create a scoped assignment from a JSON definition.","POST","/v1/namespaces/{namespace}/bindings",{bodyKind:"required-json",eventId:!0,options:[u,E]}),o("bindings get","Read one scoped assignment.","GET","/v1/namespaces/{namespace}/bindings/{binding}",{positionals:[a("binding","Binding id.")]}),o("bindings delete","Delete one scoped assignment idempotently.","DELETE","/v1/namespaces/{namespace}/bindings/{binding}",{positionals:[a("binding","Binding id.")],bodyKind:"json",eventId:!0,options:[E]}),o("bindings promote","Promote a binding when its current revision still matches.","POST","/v1/namespaces/{namespace}/bindings/{binding}/promote",{positionals:[a("binding","Binding id.")],bodyKind:"required-json",eventId:!0,options:[u,E]}),...["enable","disable","revoke"].map(e=>o(`bindings ${e}`,`${e[0].toUpperCase()}${e.slice(1)} one scoped assignment.`,"POST",`/v1/namespaces/{namespace}/bindings/{binding}/${e}`,{positionals:[a("binding","Binding id.")],bodyKind:"reason",eventId:!0,options:[E,Y]})),o("credentials providers catalog","List Credential Provider packages visible to the tenant.","GET","/v1/namespaces/{namespace}/credential-provider-catalog"),o("credentials providers list","List installed Credential Providers.","GET","/v1/namespaces/{namespace}/credential-providers"),o("credentials providers get","Read one installed Credential Provider.","GET","/v1/namespaces/{namespace}/credential-providers/{provider}",{positionals:[a("provider","Provider id.")]}),o("credentials providers install","Install a catalog Credential Provider package.","POST","/v1/namespaces/{namespace}/credential-providers/install",{bodyKind:"protected-json",options:[ke],examples:["constal credentials providers install --body @provider-setup.json"]}),o("credentials list","List Credentials without returning material.","GET","/v1/namespaces/{namespace}/credentials"),o("credentials get","Read authoritative Credential metadata.","GET","/v1/namespaces/{namespace}/credentials/{credential}",{positionals:[a("credential","Credential id.")]}),o("credentials create","Create, mint, or begin authorization for a Credential.","POST","/v1/namespaces/{namespace}/credentials",{positionals:[a("credential","New Credential id.")],bodyKind:"credential-create",options:[l("provider","CRN","Installed Credential Provider CRN.",{required:!0}),l("configuration","JSON|@FILE","Provider-defined non-secret configuration."),l("material-file","FILE","Read imported secret material from a file."),l("material-stdin",null,"Read imported secret material from stdin."),l("policies","JSON|@FILE","Optional Policy CRN array.")]}),o("credentials version","Add imported material as a scheduled Credential version.","POST","/v1/namespaces/{namespace}/credentials/{credential}/versions",{positionals:[a("credential","Credential id.")],bodyKind:"credential-version",options:[l("material-file","FILE","Read secret material from a file."),l("material-stdin",null,"Read secret material from stdin.")]}),...["activate","rotate","authorize","revoke"].map(e=>o(`credentials ${e}`,`${e[0].toUpperCase()}${e.slice(1)} a Credential lifecycle operation.`,"POST",`/v1/namespaces/{namespace}/credentials/{credential}/${e}`,{positionals:[a("credential","Credential id.")],bodyKind:"json",options:[u]})),...["consumers","uses","events"].map(e=>o(`credentials ${e}`,`List bounded Credential ${e}.`,"GET",`/v1/namespaces/{namespace}/credentials/{credential}/${e}`,{positionals:[a("credential","Credential id.")],query:e==="consumers"?[["after","after"],["limit","limit"]]:[["after","after"]],options:e==="consumers"?[S,T]:[S]})),o("channels list","List deployed Channels.","GET","/v1/namespaces/{namespace}/channels"),o("channels get","Read one deployed Channel.","GET","/v1/namespaces/{namespace}/channels/{channel}",{positionals:[a("channel","Channel id.")]}),o("channels send","Send one outbound Channel message.","POST","/v1/namespaces/{namespace}/channels/{channel}/messages",{positionals:[a("channel","Channel id.")],bodyKind:"required-json",options:[u]}),o("channels message","Read one outbound delivery receipt.","GET","/v1/namespaces/{namespace}/channels/{channel}/messages/{message}",{positionals:[a("channel","Channel id."),a("message","Message id.")]}),o("channels events","Read bounded Channel events.","GET","/v1/namespaces/{namespace}/channels/{channel}/events",{positionals:[a("channel","Channel id.")],query:[["after","after"],["limit","limit"]],options:[S,T]}),o("channels alarm","Schedule a Channel alarm.","POST","/v1/namespaces/{namespace}/channels/{channel}/alarms",{positionals:[a("channel","Channel id.")],bodyKind:"required-json",options:[u]}),o("channels alarm-get","Read one Channel alarm.","GET","/v1/namespaces/{namespace}/channels/{channel}/alarms/{alarm}",{positionals:[a("channel","Channel id."),a("alarm","Alarm id.")]}),o("channels alarm-cancel","Cancel one Channel alarm.","DELETE","/v1/namespaces/{namespace}/channels/{channel}/alarms/{alarm}",{positionals:[a("channel","Channel id."),a("alarm","Alarm id.")]}),o("policies evaluate","Evaluate a deployed Policy against a normalized test input.","POST","/v1/namespaces/{namespace}/policies/{policy}/evaluate",{positionals:[a("policy","Policy id.")],bodyKind:"required-json",options:[u]}),o("analytics summary","Read a bounded recent analytics summary.","GET","/v1/namespaces/{namespace}/analytics/summary"),...["live","dashboard","query","export"].map(e=>o(`analytics ${e}`,`${e==="export"?"Create":"Query"} ${e} analytics data.`,"POST",`/v1/namespaces/{namespace}/analytics/${e==="export"?"exports":e}`,{bodyKind:"required-json",options:[u]})),o("analytics export-get","Download one namespace-owned analytics export.","GET","/v1/namespaces/{namespace}/analytics/exports/{ref}",{positionals:[a("ref","Export artifact hash.")],binary:!0,options:[K,D]}),o("evals datasets list","List immutable Dataset Resources.","GET","/v1/namespaces/{namespace}/resources",{queryValues:{kind:"dataset"}}),o("evals datasets create","Create or idempotently initialize a Dataset draft.","POST","/v1/namespaces/{namespace}/evals/datasets/{dataset}/draft",{positionals:[a("dataset","Dataset id.")],bodyKind:"required-json",options:[u]}),o("evals datasets draft","Read a Dataset draft head.","GET","/v1/namespaces/{namespace}/evals/datasets/{dataset}/draft",{positionals:[a("dataset","Dataset id.")]}),o("evals datasets cases","Page cases in a Dataset draft.","GET","/v1/namespaces/{namespace}/evals/datasets/{dataset}/cases",{positionals:[a("dataset","Dataset id.")],query:[["after","after"],["limit","limit"]],options:[S,T]}),o("evals datasets add-case","Create or replace one caller-identified Dataset case.","POST","/v1/namespaces/{namespace}/evals/datasets/{dataset}/cases",{positionals:[a("dataset","Dataset id.")],bodyKind:"required-json",options:[u]}),o("evals datasets delete-case","Delete one case from a Dataset draft.","DELETE","/v1/namespaces/{namespace}/evals/datasets/{dataset}/cases/{case}",{positionals:[a("dataset","Dataset id."),a("case","Case id.")]}),o("evals datasets capture","Capture a recorded Agent interaction into a Dataset draft.","POST","/v1/namespaces/{namespace}/evals/datasets/{dataset}/capture",{positionals:[a("dataset","Dataset id.")],bodyKind:"required-json",options:[u]}),o("evals datasets publish","Publish the current Dataset draft as an immutable version.","POST","/v1/namespaces/{namespace}/evals/datasets/{dataset}/publish",{positionals:[a("dataset","Dataset id.")],bodyKind:"required-json",options:[u]}),o("evals scores start","Score a pinned Subject asynchronously and append its verdict to the judged Session.","POST","/v1/namespaces/{namespace}/evals/scores",{bodyKind:"required-json",options:[u,se]}),o("evals scores get","Read one durable scoring job.","GET","/v1/namespaces/{namespace}/evals/scores/{score}",{positionals:[a("score","Score job id.")]}),o("evals scores cancel","Cancel one durable scoring job.","POST","/v1/namespaces/{namespace}/evals/scores/{score}/cancel",{positionals:[a("score","Score job id.")],bodyKind:"optional-json",options:[u]}),o("evals labels request","Open a durable, schema-checked human labeling wait.","POST","/v1/namespaces/{namespace}/evals/labels",{bodyKind:"required-json",options:[u,se]}),o("evals scorers list","List versioned Scorer Resources.","GET","/v1/namespaces/{namespace}/resources",{queryValues:{kind:"scorer"}}),o("evals scorers create","Create a versioned code, Judge Agent, or human-review Scorer.","POST","/v1/namespaces/{namespace}/evals/scorers",{bodyKind:"required-json",options:[u]}),o("evals scorers get","Read one Scorer Resource.","GET","/v1/namespaces/{namespace}/resources/scorer/{scorer}",{positionals:[a("scorer","Scorer id.")]}),o("evals suites list","Page evaluation suites by most recent activity.","GET","/v1/namespaces/{namespace}/evals/suites",{query:[["after","after"],["limit","limit"]],options:[S,T]}),o("evals suites start","Run a fresh suite over an immutable Dataset.","POST","/v1/namespaces/{namespace}/evals/suites",{bodyKind:"required-json",options:[u]}),o("evals suites get","Read authoritative suite progress and results.","GET","/v1/namespaces/{namespace}/evals/suites/{suite}",{positionals:[a("suite","Suite id.")]}),o("evals suites cancel","Cancel a running evaluation suite.","POST","/v1/namespaces/{namespace}/evals/suites/{suite}/cancel",{positionals:[a("suite","Suite id.")],bodyKind:"json",options:[u]}),o("evals compare","Compare paired suite and baseline verdicts.","POST","/v1/namespaces/{namespace}/evals/compare",{bodyKind:"required-json",options:[u]}),o("evals baseline","Set an Agent's evaluation baseline.","POST","/v1/namespaces/{namespace}/evals/baseline",{bodyKind:"required-json",options:[u]}),o("evals policy get","Read the namespace eval door policy pinned at Run admission.","GET","/v1/namespaces/{namespace}/evals/policy"),o("evals policy set","Atomically set sampling rates, Scorers, and eval budget ceilings.","PUT","/v1/namespaces/{namespace}/evals/policy",{bodyKind:"required-json",options:[u]}),o("evals samples list","Page asynchronous live-traffic scoring dispatches.","GET","/v1/namespaces/{namespace}/evals/samples",{query:[["before","before"],["limit","limit"]],options:[l("before","TIMESTAMP","Read samples created before this millisecond timestamp."),T]}),o("evals schedules list","List continuous evaluation schedules.","GET","/v1/namespaces/{namespace}/evals/schedules"),o("evals schedules get","Read one continuous evaluation schedule.","GET","/v1/namespaces/{namespace}/evals/schedules/{schedule}",{positionals:[a("schedule","Schedule id.")]}),o("evals schedules apply","Create or atomically update a continuous evaluation schedule.","PUT","/v1/namespaces/{namespace}/evals/schedules/{schedule}",{positionals:[a("schedule","Schedule id.")],bodyKind:"required-json",options:[u]}),o("evals schedules delete","Delete one exact continuous evaluation schedule revision.","DELETE","/v1/namespaces/{namespace}/evals/schedules/{schedule}",{positionals:[a("schedule","Schedule id.")],bodyKind:"schedule-delete",options:[l("expected-hash","HASH","Current schedule hash.",{required:!0})]}),o("evals schedules run","Run a scheduled Suite now without changing its cadence.","POST","/v1/namespaces/{namespace}/evals/schedules/{schedule}/run",{positionals:[a("schedule","Schedule id.")],bodyKind:"json",eventId:!0,options:[E]}),o("evals training providers","List installed Training Providers and checkpoint capabilities.","GET","/v1/namespaces/{namespace}/evals/training-providers"),o("evals training models","List models and pinned prices advertised by one Training Provider.","GET","/v1/namespaces/{namespace}/evals/training-models",{query:[["provider","provider"],["hash","hash"]],options:[l("provider","CRN","Training Provider Resource CRN."),l("hash","HASH","Exact Training Provider Resource hash.")]}),o("evals training list","Page fine-tuning and reinforcement-learning jobs.","GET","/v1/namespaces/{namespace}/evals/training-jobs",{query:[["after","after"],["limit","limit"]],options:[S,T]}),o("evals training start","Start a durable metered SFT or RL job.","POST","/v1/namespaces/{namespace}/evals/training-jobs",{bodyKind:"required-json",options:[u]}),o("evals training get","Read authoritative training progress, usage, and results.","GET","/v1/namespaces/{namespace}/evals/training-jobs/{job}",{positionals:[a("job","Training job id.")]}),o("evals training cancel","Cancel a running training job.","POST","/v1/namespaces/{namespace}/evals/training-jobs/{job}/cancel",{positionals:[a("job","Training job id.")],bodyKind:"json",options:[u]}),o("evals training checkpoint-gateways","List exact Gateway revisions compatible with one durable checkpoint.","GET","/v1/namespaces/{namespace}/evals/training-jobs/{job}/checkpoint-gateways",{positionals:[a("job","Succeeded Training Job id.")],query:[["step","step"],["ref","ref"]],options:[l("step","COUNT","Exact checkpoint step."),l("ref","HASH","Exact checkpoint Artifact hash.")]}),o("evals training create-model","Import a checkpoint through a compatible Gateway and create a Model.","POST","/v1/namespaces/{namespace}/evals/training-jobs/{job}/models",{positionals:[a("job","Succeeded Training Job id.")],bodyKind:"required-json",options:[u]}),o("memory stores list","List configured Memory Stores.","GET","/v1/namespaces/{namespace}/resources",{queryValues:{kind:"memory-store"}}),o("memory stores create","Create a Memory Store Resource.","POST","/v1/namespaces/{namespace}/resources",{bodyKind:"resource-kind",resourceKind:"memory-store",options:[u]}),...["get","delete"].map(e=>o(`memory stores ${e}`,`${e==="get"?"Read":"Delete"} one Memory Store.`,e==="get"?"GET":"DELETE","/v1/namespaces/{namespace}/resources/memory-store/{id}",{positionals:[a("id","Memory Store id.")]})),o("memory list","List configured Memory Resources.","GET","/v1/namespaces/{namespace}/resources",{queryValues:{kind:"memory"}}),o("memory create","Create a Memory Resource.","POST","/v1/namespaces/{namespace}/resources",{bodyKind:"resource-kind",resourceKind:"memory",options:[u]}),...["get","delete"].map(e=>o(`memory ${e}`,`${e==="get"?"Read":"Delete"} one Memory Resource.`,e==="get"?"GET":"DELETE","/v1/namespaces/{namespace}/resources/memory/{id}",{positionals:[a("id","Memory id.")]})),o("customers list","List downstream customers.","GET","/v1/customers"),o("customers get","Read one downstream customer.","GET","/v1/customers/{customer}",{positionals:[a("customer","Customer id.")]}),o("customers put","Create or update a downstream customer.","PUT","/v1/customers/{customer}",{positionals:[a("customer","Customer id.")],bodyKind:"required-json",eventId:!0,options:[u,E]}),...["enable","disable"].map(e=>o(`customers ${e}`,`${e[0].toUpperCase()}${e.slice(1)} a downstream customer.`,"POST",`/v1/customers/{customer}/${e}`,{positionals:[a("customer","Customer id.")],bodyKind:"reason",eventId:!0,options:[E,Y]})),...[["map","Map an external identity to a downstream customer.","PUT","identity-mappings"],["unmap","Remove an external identity mapping from a downstream customer.","DELETE","identity-mappings"],["bind-policy","Bind a Policy to a downstream customer.","PUT","policy-bindings"],["unbind-policy","Remove a Policy binding from a downstream customer.","DELETE","policy-bindings"]].map(([e,n,t,s])=>o(`customers ${e}`,n,t,`/v1/customers/{customer}/${s}/{binding}`,{positionals:[a("customer","Customer id."),a("binding","Mapping or binding id.")],bodyKind:"required-json",eventId:!0,options:[u,E]})),o("artifacts get","Download an authorized content-addressed artifact.","GET","/v1/artifacts/{ref}",{positionals:[a("ref","Artifact hash.")],binary:!0,options:[K,D]}),o("exports get","Download a redacted durable export.","GET","/v1/exports/{ref}",{positionals:[a("ref","Export hash.")],binary:!0,options:[K,D]}),o("anchors get","Download an authorized customer audit anchor.","GET","/v1/anchors/{ref}",{positionals:[a("ref","Anchor hash.")],binary:!0,options:[K,D]}),o("stages get","Inspect one map/reduce stage.","GET","/v1/stages/{stage}",{positionals:[a("stage","Stage hash.")]}),o("stages recover","Request authorized stage recovery.","POST","/v1/stages/{stage}/recover",{positionals:[a("stage","Stage hash.")],bodyKind:"json",options:[u]}),o("tables get","Read a table branch head and state.","GET","/v1/namespaces/{namespace}/tables/{table}",{positionals:[a("table","Table id.")],query:[["branch","branch"]],options:[l("branch","NAME","Table branch; defaults to main.")]}),o("tables export-get","Read an exact table catalog commit, export, or intent.","GET","/v1/namespaces/{namespace}/table-exports/{table}/{branch}/{sequence}/{hash}",{positionals:[a("table","Table id."),a("branch","Branch name."),a("sequence","Commit sequence."),a("hash","Commit hash.")],binary:!0,options:[K,D]})]);function G(e){return e.path.join(" ")}function Ce(e=_){let n=new Set;for(let t of e){let s=G(t);if(n.has(s))throw new TypeError(`duplicate CLI command ${s}`);if(n.add(s),!t.summary||!t.local&&(!t.method||!t.route))throw new TypeError(`invalid CLI command ${s}`);let i=t.positionals??[];if(new Set(i.map(c=>c.name)).size!==i.length)throw new TypeError(`duplicate positional in ${s}`);let r=t.options??[];if(new Set(r.map(c=>c.name)).size!==r.length)throw new TypeError(`duplicate option in ${s}`);for(let c of t.route?.matchAll(/\{([^}]+)\}/gu)??[])if(c[1]!=="namespace"&&!i.some(d=>d.name===c[1]))throw new TypeError(`unknown route placeholder ${c[1]} in ${s}`)}return e}Ce();import{randomUUID as Pe}from"node:crypto";import{chmod as ae,mkdir as xe,readFile as Ne,rename as Ie,unlink as qe,writeFile as Le}from"node:fs/promises";import{homedir as Ke}from"node:os";import{dirname as De,join as z}from"node:path";var B="https://platform.constal.ai",Ge=/^[a-z0-9][a-z0-9._-]{0,127}$/u;function Me(e=process.env){return e.CONSTAL_CONFIG_DIR||z(e.XDG_CONFIG_HOME||z(Ke(),".config"),"constal")}function J(e=process.env){let n=Me(e);return{root:n,context:z(n,"config.json"),credentials:z(n,"credentials.json")}}async function V(e){try{let n=JSON.parse(await Ne(e,"utf8"));return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}catch(n){if(n?.code==="ENOENT")return{};throw new TypeError(`Cannot read Constal configuration at ${e}: ${n instanceof Error?n.message:String(n)}`)}}async function oe(e,n,t){await xe(De(e),{recursive:!0,mode:448});let s=`${e}.${process.pid}.${Pe()}.tmp`;await Le(s,`${JSON.stringify(n,null,2)}
3
3
  `,{mode:t}),await ae(s,t),await Ie(s,e),await ae(e,t)}function re(e){let n;try{n=new URL(String(e||B))}catch{throw new TypeError("Platform origin must be an absolute HTTPS URL")}if(n.protocol!=="https:"||n.username||n.password||n.search||n.hash)throw new TypeError("Platform origin must be an absolute HTTPS URL");return n.origin+n.pathname.replace(/\/+$/u,"")}function F(e,n){if(e==null||e==="")return null;if(!Ge.test(String(e)))throw new TypeError(`${n} is invalid`);return String(e)}async function ie({environment:e=process.env,overrides:n={}}={}){let t=J(e),[s,i]=await Promise.all([V(t.context),V(t.credentials)]),r=F(n.namespace??e.CONSTAL_NAMESPACE??s.namespace??"default","namespace"),c=F(n.tenant??e.CONSTAL_TENANT??s.tenant??null,"tenant"),d=typeof e.CONSTAL_API_KEY=="string"&&e.CONSTAL_API_KEY.trim()?e.CONSTAL_API_KEY.trim():null,p=typeof i.apiKey=="string"&&i.apiKey.trim()?i.apiKey.trim():null;return{origin:re(n.origin??e.CONSTAL_PLATFORM_URL??s.origin??B),namespace:r,tenant:c,apiKey:d??p,credentialSource:d?"environment":p?"credentials-file":"none",paths:t}}async function ce(e,{environment:n=process.env}={}){let t=J(n),s=await V(t.context),i=e.clearTenant?null:F(e.tenant??s.tenant??null,"tenant"),r={origin:re(e.origin??s.origin??B),namespace:F(e.namespace??s.namespace??"default","namespace"),...i?{tenant:i}:{}};return await oe(t.context,r,384),r}async function de(e,{environment:n=process.env}={}){let t=String(e??"").trim();if(!t||t.length>16384||/[\r\n]/u.test(t))throw new TypeError("Constal API key is invalid");let s=J(n);return await oe(s.credentials,{apiKey:t},384),s.credentials}async function le({environment:e=process.env}={}){let n=J(e).credentials;try{return await qe(n),!0}catch(t){if(t?.code==="ENOENT")return!1;throw t}}var Ct=Object.freeze({origin:B,namespace:"default"});import{createHash as Z}from"node:crypto";import{lstat as Ue,readFile as M,readdir as pe,realpath as ue,stat as me}from"node:fs/promises";import{basename as _e,dirname as X,posix as fe,relative as ze,resolve as O}from"node:path";import{gzipSync as Fe}from"node:zlib";var he=new Set([".git",".hg",".svn",".constal",".venv","__pycache__",".pytest_cache",".mypy_cache",".ruff_cache",".next",".turbo","coverage","dist","node_modules"]),Be=new Set([".npmrc",".pypirc",".DS_Store"]),Je=8*1024*1024,He=64*1024*1024,Ye=2e3;function P(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function ye(e){let n=e?.workspaces;return(Array.isArray(n)?n:Array.isArray(P(n)?.packages)?n.packages:[]).filter(s=>typeof s=="string"&&s.length>0&&s.length<=1024)}function ge(e){let n="^";for(let t=0;t<e.length;t+=1){let s=e[t];s==="*"&&e[t+1]==="*"?(n+=".*",t+=1):s==="*"?n+="[^/]*":s==="?"?n+="[^/]":n+=s.replace(/[\\^$.*+?()[\]{}|]/gu,"\\$&")}return new RegExp(`${n}/?$`,"u")}function We(e){return{...P(e?.dependencies),...P(e?.devDependencies),...P(e?.optionalDependencies),...P(e?.peerDependencies)}}async function Ve(e,n,t){let s=ye(t).map(ge),i=new Map,r=0;async function c(f,w=""){for(let y of await pe(f,{withFileTypes:!0})){if(!y.isDirectory()||he.has(y.name)||++r>2e4)continue;let v=w?fe.join(w,y.name):y.name,b=O(f,y.name);if(s.some(g=>g.test(v)))try{let g=P(JSON.parse(await M(O(b,"package.json"),"utf8")));g&&typeof g.name=="string"&&g.name&&i.set(g.name,{root:v,packageJson:g})}catch(g){if(g?.code!=="ENOENT")throw new TypeError(`workspace package.json must be valid JSON: ${g instanceof Error?g.message:String(g)}`)}await c(b,v)}}await c(e);let d=[...i.values()].find(f=>f.root===n);if(!d)return[n];let p=new Set([n]),h=[d];for(;h.length;){let f=h.shift();for(let w of Object.keys(We(f.packageJson))){let y=i.get(w);!y||p.has(y.root)||(p.add(y.root),h.push(y))}}return[...p].sort()}async function Xe(e){let n=await ue(O(e)),t=X(n);for(let s=0;s<32&&t!==X(t);s+=1,t=X(t)){let i;try{i=P(JSON.parse(await M(O(t,"package.json"),"utf8")))}catch(c){if(c?.code==="ENOENT")continue;throw new TypeError(`workspace package.json must be valid JSON: ${c instanceof Error?c.message:String(c)}`)}if(!i)throw new TypeError("workspace package.json must contain a JSON object");let r=ze(t,n).replaceAll("\\","/");if(!r.startsWith("../")&&ye(i).some(c=>ge(c).test(r)))return{archiveRoot:t,projectRoot:r,workspaceRoots:await Ve(t,r,i)}}return{archiveRoot:n,projectRoot:null,workspaceRoots:null}}function Ze(e){return e===".env.example"||e===".env.sample"||e===".env.template"?!1:e===".env"||e.startsWith(".env.")}function Qe(e){let n=e.endsWith("/"),t=e.startsWith("/"),s=e.replace(/^\/+|\/+$/gu,"");if(!s||s.startsWith("#"))return null;let i="";for(let r=0;r<s.length;r++){let c=s[r];c==="*"&&s[r+1]==="*"?(i+=".*",r++):c==="*"?i+="[^/]*":c==="?"?i+="[^/]":i+=c.replace(/[|\\{}()[\]^$+?.]/gu,"\\$&")}return{directory:n,regex:new RegExp(`${t?"^":"(?:^|/)"}${i}${n?"(?:/|$)":"$"}`,"u")}}async function et(e){let n="";try{n=await M(O(e,".constalignore"),"utf8")}catch(t){if(t?.code!=="ENOENT")throw t}return n.split(/\r?\n/gu).map(t=>t.trim()).filter(t=>t&&!t.startsWith("!")).map(Qe).filter(Boolean)}function tt(e,n,t){let s=_e(e);return n&&he.has(s)||!n&&(Be.has(s)||Ze(s))?!0:t.some(i=>(!i.directory||n)&&i.regex.test(e))}async function nt(e,n={}){let t=await ue(O(e));if(!(await me(t)).isDirectory())throw new TypeError("deployment source must be a directory, archive, or immutable Git URL");let i=await et(t),r=[],c=0,d=Array.isArray(n.workspaceRoots)?n.workspaceRoots:null;function p(f){return!d||d.some(w=>w===f||w.startsWith(`${f}/`)||f.startsWith(`${w}/`))}async function h(f,w=""){let y=await pe(f,{withFileTypes:!0});y.sort((v,b)=>v.name.localeCompare(b.name));for(let v of y){let b=w?fe.join(w,v.name):v.name;if(v.isDirectory()&&!p(b)||tt(b,v.isDirectory(),i))continue;let g=O(f,v.name),j=await Ue(g);if(j.isSymbolicLink())throw new TypeError(`deployment source contains a symbolic link: ${b}`);if(j.isDirectory())r.push({path:`${b}/`,type:"directory",mode:493,bytes:Buffer.alloc(0)}),await h(g,b);else if(j.isFile()){if(j.size>Je)throw new TypeError(`deployment source file exceeds 8 MiB: ${b}`);if(c+=j.size,c>He)throw new TypeError("deployment source exceeds 64 MiB expanded");r.push({path:b,type:"file",mode:j.mode&73?493:420,bytes:await M(g)})}else throw new TypeError(`deployment source contains an unsupported entry: ${b}`);if(r.length>Ye)throw new TypeError("deployment source contains more than 2,000 entries")}}if(await h(t),!r.some(f=>f.type==="file"))throw new TypeError("deployment source contains no files");return r}function C(e,n,t,s){let i=Buffer.from(n,"utf8");if(i.byteLength>s)throw new TypeError(`archive path component is too long: ${n}`);i.copy(e,t)}function I(e,n,t,s,i=!1){let r=i?"\0 ":"\0",c=Math.trunc(n).toString(8).padStart(s-r.length,"0")+r;C(e,c,t,s)}function st(e){if(Buffer.byteLength(e)<=100)return{name:e,prefix:""};for(let t=e.lastIndexOf("/");t>0;t=e.lastIndexOf("/",t-1)){let s=e.slice(0,t),i=e.slice(t+1);if(Buffer.byteLength(i)<=100&&Buffer.byteLength(s)<=155)return{name:i,prefix:s}}throw new TypeError(`archive path exceeds the portable tar limit: ${e}`)}function at(e){let n=Buffer.alloc(512),t=e.type==="directory"?e.path.replace(/\/+$/u,""):e.path,{name:s,prefix:i}=st(t);C(n,s,0,100),I(n,e.mode,100,8),I(n,0,108,8),I(n,0,116,8),I(n,e.type==="file"?e.bytes.byteLength:0,124,12),I(n,0,136,12),n.fill(32,148,156),n[156]=e.type==="directory"?53:48,C(n,"ustar\0",257,6),C(n,"00",263,2),C(n,"constal",265,32),C(n,"constal",297,32),i&&C(n,i,345,155);let r=0;for(let c of n)r+=c;return I(n,r,148,8,!0),n}async function ot(e,n={}){let t=await nt(e,n),s=[];for(let i of t)if(s.push(at(i)),i.type==="file"){s.push(i.bytes);let r=i.bytes.byteLength%512;r&&s.push(Buffer.alloc(512-r))}return s.push(Buffer.alloc(1024)),Fe(Buffer.concat(s),{level:9,mtime:0})}function rt(e){let n;try{n=new URL(e)}catch{return null}if(n.protocol!=="https:"||!/^[a-f0-9]{40}$/u.test(n.hash.slice(1).toLowerCase()))return null;let t=Buffer.from(JSON.stringify({gitUrl:n.toString()}));return{body:t,contentType:"application/json",idempotencyKey:`sha256-${Z("sha256").update(t).digest("hex")}`}}async function ve(e,n=M){let t=rt(e);if(t)return t;let s;try{s=await me(O(e))}catch(c){throw c?.code==="ENOENT"?new TypeError(`deployment source does not exist: ${e}`):c}if(s.isDirectory()){let c=await Xe(e),d=await ot(c.archiveRoot,{workspaceRoots:c.workspaceRoots}),p=Z("sha256").update(d).update("\0").update(c.projectRoot??"").digest("hex");return{body:d,contentType:"application/gzip",idempotencyKey:`sha256-${p}`,...c.projectRoot?{projectRoot:c.projectRoot}:{}}}if(!s.isFile())throw new TypeError("deployment source must be a directory, archive, or immutable Git URL");let i=/\.(?:tar\.gz|tgz)$/iu.test(e);if(!i&&!/\.zip$/iu.test(e))throw new TypeError("deployment archive must end in .zip, .tar.gz, or .tgz");let r=await n(e);return{body:r,contentType:i?"application/gzip":"application/zip",idempotencyKey:`sha256-${Z("sha256").update(r).digest("hex")}`}}function be(e){return e==null?"\u2014":typeof e=="object"?JSON.stringify(e):String(e)}function it(e){return Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.data)?e.data:e&&typeof e=="object"?Object.entries(e).map(([n,t])=>({field:n,value:t})):[{value:e}]}function ct(e){let n=it(e);if(!n.length)return`No results
4
4
  `;let t=n.map(c=>c&&typeof c=="object"&&!Array.isArray(c)?c:{value:c}),s=[...new Set(t.flatMap(c=>Object.keys(c)))].slice(0,8),i=s.map(c=>Math.min(48,Math.max(c.length,...t.map(d=>be(d[c]).length)))),r=c=>s.map((d,p)=>{let h=be(c[d]),f=i[p];return(h.length>f?`${h.slice(0,Math.max(1,f-1))}\u2026`:h).padEnd(f)}).join(" ").trimEnd();return`${r(Object.fromEntries(s.map(c=>[c,c.toUpperCase()])))}
5
5
  ${t.map(r).join(`
@@ -7,7 +7,7 @@ ${t.map(r).join(`
7
7
  `}function we(e,n="table"){return n==="json"?`${JSON.stringify(e,null,2)}
8
8
  `:n==="jsonl"?`${(Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.data)?e.data:[e]).map(s=>JSON.stringify(s)).join(`
9
9
  `)}
10
- `:ct(e)}var Re="1.1.0",m=class extends Error{constructor(n){super(n),this.name="CliUsageError",this.exitCode=2}},R=class extends Error{constructor(n,t,s=null){super(`Platform API returned ${n}${t?`: ${t}`:""}${s?` (request ${s})`:""}`),this.name="CliApiError",this.exitCode=1,this.status=n,this.requestId=s}},yt={stdin:mt,stdout:ft,stderr:ht,environment:process.env,fetch:globalThis.fetch,readFile:pt,writeFile:ut,randomUUID:lt};function $(e,n){e.write(String(n))}async function H(e){let n=[];for await(let t of e)n.push(typeof t=="string"?Buffer.from(t):t);return Buffer.concat(n).toString("utf8")}async function gt(e,n){return!e.stdin.isTTY||typeof e.stdin.setRawMode!="function"?(await H(e.stdin)).trim():($(e.stderr,n),e.stdin.setRawMode(!0),e.stdin.resume(),new Promise((t,s)=>{let i="",r=()=>{e.stdin.off("data",c),e.stdin.setRawMode(!1),e.stdin.pause(),$(e.stderr,`
10
+ `:ct(e)}var Re="1.2.0",m=class extends Error{constructor(n){super(n),this.name="CliUsageError",this.exitCode=2}},R=class extends Error{constructor(n,t,s=null){super(`Platform API returned ${n}${t?`: ${t}`:""}${s?` (request ${s})`:""}`),this.name="CliApiError",this.exitCode=1,this.status=n,this.requestId=s}},yt={stdin:mt,stdout:ft,stderr:ht,environment:process.env,fetch:globalThis.fetch,readFile:pt,writeFile:ut,randomUUID:lt};function $(e,n){e.write(String(n))}async function H(e){let n=[];for await(let t of e)n.push(typeof t=="string"?Buffer.from(t):t);return Buffer.concat(n).toString("utf8")}async function gt(e,n){return!e.stdin.isTTY||typeof e.stdin.setRawMode!="function"?(await H(e.stdin)).trim():($(e.stderr,n),e.stdin.setRawMode(!0),e.stdin.resume(),new Promise((t,s)=>{let i="",r=()=>{e.stdin.off("data",c),e.stdin.setRawMode(!1),e.stdin.pause(),$(e.stderr,`
11
11
  `)},c=d=>{for(let p of Buffer.from(d)){if(p===3){r(),s(new m("Authentication cancelled"));return}if(p===13||p===10){r(),t(i.trim());return}if(p===127||p===8){i=i.slice(0,-1);continue}p>=32&&(i+=String.fromCharCode(p))}};e.stdin.on("data",c)}))}function Q(e){let n=new Map;for(let t of[...W,...e?.options??[]])n.set(t.name,t);return[...n.values()]}function Ee(e){let n=`--${e.name}${e.value?` <${e.value}>`:""}`,t=`${e.required?" Required.":e.choices?` Values: ${e.choices.join(", ")}.`:""}${e.repeatable?" May be repeated.":""}`;return` ${n.padEnd(28)} ${e.description}${t}`}function Te(e=null){if(!e){let s=new Map;for(let i of _){let r=i.path[0],c=s.get(r)??[];c.push(i),s.set(r,c)}return`Constal CLI ${Re}
12
12
 
13
13
  Usage:
@@ -41,8 +41,8 @@ ${Q(e).map(Ee).join(`
41
41
  Examples:
42
42
  ${e.examples.map(s=>` ${s}`).join(`
43
43
  `)}`:""}
44
- `}function vt(e){return[..._].sort((n,t)=>t.path.length-n.path.length).find(n=>n.path.every((t,s)=>e[s]===t))}function bt(e,n){let t={},s=[],i=new Map(Q(e).map(d=>[d.name,d]));for(let d=0;d<n.length;d++){let p=n[d];if(p==="--"){s.push(...n.slice(d+1));break}if(!p.startsWith("--")){s.push(p);continue}let[h,f]=p.slice(2).split(/=(.*)/su,2),w=h.startsWith("no-"),y=w?h.slice(3):h,v=i.get(y);if(!v)throw new m(`Unknown option --${h} for ${G(e)}`);if(v.value){if(w)throw new m(`--no-${y} is not valid`);let b=f??n[++d];if(b===void 0||b.startsWith("--"))throw new m(`--${y} requires a value`);if(v.choices&&!v.choices.includes(b))throw new m(`--${y} must be one of ${v.choices.join(", ")}`);t[y]=v.repeatable?[...t[y]??[],b]:b}else t[y]=!w}let r=e.positionals??[];if(s.length<r.filter(d=>!d.optional).length||s.length>r.length)throw new m(`Expected ${r.map(d=>`<${d.name}>`).join(" ")||"no arguments"}`);let c=Object.fromEntries(r.map((d,p)=>[d.name,s[p]]));for(let d of e.options??[])if(d.required&&t[d.name]===void 0)throw new m(`--${d.name} is required`);return{options:t,values:c}}function je(e){let n={};for(let t of e??[]){let s=String(t).indexOf("="),i=s<0?"":String(t).slice(0,s),r=s<0?"":String(t).slice(s+1);if(!/^[A-Za-z][A-Za-z0-9._-]{0,127}$/u.test(i)||!/^crn:constal:[^\s]{1,1000}$/u.test(r))throw new m("--bind must use NAME=CRN with a valid binding name and Constal Resource CRN");if(Object.hasOwn(n,i)&&n[i]!==r)throw new m(`--bind ${i} was supplied with different Resources`);n[i]=r}return Object.keys(n).length?JSON.stringify(Object.fromEntries(Object.entries(n).sort(([t],[s])=>t.localeCompare(s)))):null}async function wt(e,n,t){if(e!==void 0)return e==="@-"?(await H(n.stdin)).trim():e.startsWith("@")?(await n.readFile(e.slice(1),"utf8")).trim():e}async function U(e,n,t,s){let i=await wt(e,n,t);if(i===void 0)return s;try{return JSON.parse(i)}catch{throw new m(`${t} must be valid JSON, @FILE, or @-`)}}async function k(e,n,t,s){let i=await U(e,n,t,s);if(!i||typeof i!="object"||Array.isArray(i))throw new m(`${t} must be a JSON object`);return i}async function Se(e,n){if(e["material-file"]&&e["material-stdin"])throw new m("Choose only one material source");if(e["material-file"])return(await n.readFile(e["material-file"],"utf8")).replace(/[\r\n]+$/u,"");if(e["material-stdin"])return(await H(n.stdin)).replace(/[\r\n]+$/u,"")}function ee(e,n=[]){if(typeof e=="string")n.push(e);else if(Array.isArray(e))for(let t of e)ee(t,n);else if(e&&typeof e=="object")for(let t of Object.values(e))ee(t,n);return n}async function Et(e,n,t){let{options:s,values:i}=n,r,c=[];switch(e.bodyKind){case void 0:return{body:void 0,headers:{},sensitiveValues:c};case"archive":{let d=await t.readFile(i.archive),p=/\.(?:tar\.gz|tgz)$/iu.test(i.archive);if(!p&&!/\.zip$/iu.test(i.archive))throw new m("Deployment archive must end in .zip, .tar.gz, or .tgz");let h=s["idempotency-key"]??`sha256-${dt("sha256").update(d).digest("hex")}`;return{body:d,headers:{"content-type":p?"application/gzip":"application/zip","idempotency-key":h},sensitiveValues:c}}case"required-json":if(s.body===void 0)throw new m("--body is required");r=await k(s.body,t,"body");break;case"optional-json":r=await k(s.body,t,"body",{});break;case"protected-json":if(s.body===void 0)throw new m("--body is required");if(!s.body.startsWith("@"))throw new m("This setup document must be read from @FILE or @-");r=await k(s.body,t,"body"),c.push(...ee(r));break;case"resource-kind":if(s.body===void 0)throw new m("--body is required");r={...await k(s.body,t,"body"),kind:e.resourceKind};break;case"json":r=await k(s.body,t,"body",{});break;case"reason":r={...s.reason?{reason:s.reason}:{}};break;case"run-start":{r={body:await U(s.data,t,"data",{}),deliver:s.deliver??"queue",...s.tags===void 0?{}:{tags:await k(s.tags,t,"tags",{})}};break}case"wait-resolve":if(s.value===void 0)throw new m("--value is required");r={value:await U(s.value,t,"value")};break;case"steer":r={text:s.text,...s.data===void 0?{}:{data:await U(s.data,t,"data")}};break;case"interrupt":r={...await k(s.body,t,"body",{}),mode:s.mode};break;case"rollout-control":r={deploymentRevision:s.deployment,reason:s.reason};break;case"schedule-delete":r={expectedHash:s["expected-hash"]};break;case"credential-create":{let d=await Se(s,t);r={id:i.credential,provider:s.provider,configuration:await k(s.configuration,t,"configuration",{}),...s.policies===void 0?{}:{policies:await U(s.policies,t,"policies")},...d===void 0?{}:{material:d}},d!==void 0&&c.push(d);break}case"credential-version":{let d=await Se(s,t);if(d===void 0)throw new m("--material-file or --material-stdin is required");c.push(d),r={material:d};break}default:throw new m(`Unsupported request body kind ${e.bodyKind}`)}if(!r||typeof r!="object"||Array.isArray(r))throw new m("Request body must be a JSON object");return e.eventId&&r.eventId===void 0&&(r.eventId=s["event-id"]??t.randomUUID()),{body:JSON.stringify(r),headers:{"content-type":"application/json"},sensitiveValues:c}}function $e(e,n,t){let s={...n.values,namespace:t.namespace},i=e.route.replace(/\{([^}]+)\}/gu,(c,d)=>encodeURIComponent(s[d])),r=new URL(`${t.origin}${i}`);for(let[c,d]of e.query??[])n.options[c]!==void 0&&r.searchParams.set(d,n.options[c]);for(let[c,d]of Object.entries(e.queryValues??{}))r.searchParams.set(c,d);return r}async function q(e){return(e.headers.get("content-type")??"").includes("json")?e.json().catch(()=>null):e.text()}function te(e){return typeof e=="string"?e:typeof e?.error=="string"?e.error:typeof e?.error?.message=="string"?e.error.message:typeof e?.message=="string"?e.message:e==null?"request failed":JSON.stringify(e)}function L(e,n){let t=String(e??"");for(let s of n)s&&(t=t.replaceAll(String(s),"[REDACTED]"));return t}async function Oe(e,n,t,s){if(!t.apiKey)throw new m("No API key is configured. Set CONSTAL_API_KEY or run constal auth login");let i=$e(e,n,t),r=await Et(e,n,s),c=new Headers({authorization:`Bearer ${t.apiKey}`,accept:e.stream?"text/event-stream":"application/json",...r.headers});t.tenant&&c.set("x-constal-tenant",t.tenant),n.options["mastra-storage"]&&c.set("x-constal-mastra-storage",n.options["mastra-storage"]);let d=je(n.options.bind);d&&c.set("x-constal-framework-bindings",d);let p;try{p=await s.fetch(i,{method:e.method,headers:c,...r.body===void 0?{}:{body:r.body}})}catch(h){let f=h instanceof Error?h.message:"network request failed";throw new R(0,L(f,[t.apiKey,...r.sensitiveValues]))}if(!p.ok){let h=await q(p),f=L(te(h),[t.apiKey,...r.sensitiveValues]);throw new R(p.status,f,p.headers.get("x-request-id"))}if(e.stream){if(!p.body)return null;for await(let h of p.body)s.stdout.write(h);return null}if(e.binary){let h=new Uint8Array(await p.arrayBuffer());return n.options.out?(await s.writeFile(n.options.out,h,{mode:384}),n.options.quiet||$(s.stderr,`Wrote ${h.byteLength} bytes to ${n.options.out}
45
- `)):s.stdout.write(h),null}return q(p)}async function Tt(e,n,t,s){if(!t.apiKey)throw new m("No API key is configured. Set CONSTAL_API_KEY or run constal auth login");let i=n.values.source??".",r;try{r=await ve(i,s.readFile)}catch(g){throw new m(g instanceof Error?g.message:String(g))}let c=n.options.timeout===void 0?600:Number(n.options.timeout);if(!Number.isSafeInteger(c)||c<1||c>3600)throw new m("--timeout must be an integer between 1 and 3600 seconds");let d=$e(e,n,t),p=new Headers({authorization:`Bearer ${t.apiKey}`,accept:"application/json","content-type":r.contentType,"idempotency-key":n.options["idempotency-key"]??r.idempotencyKey,"x-constal-namespace":t.namespace});t.tenant&&p.set("x-constal-tenant",t.tenant),r.projectRoot&&p.set("x-constal-project-root",r.projectRoot),n.options["mastra-storage"]&&p.set("x-constal-mastra-storage",n.options["mastra-storage"]);let h=je(n.options.bind);h&&p.set("x-constal-framework-bindings",h);let f;try{f=await s.fetch(d,{method:"POST",headers:p,body:r.body})}catch(g){throw new R(0,L(g instanceof Error?g.message:"network request failed",[t.apiKey]))}if(!f.ok){let g=await q(f);throw new R(f.status,L(te(g),[t.apiKey]),f.headers.get("x-request-id"))}let w=await q(f),y=w?.data??w,v=y?.deploymentRevision;if(n.options.wait===!1||typeof v!="string"||y.status==="deployed")return y;let b=Date.now()+c*1e3;for(;Date.now()<b;){await new Promise(N=>setTimeout(N,1e3));let g=new URL(`${t.origin}/v1/deployments/${encodeURIComponent(v)}`),j=new Headers({authorization:`Bearer ${t.apiKey}`,accept:"application/json"});t.tenant&&j.set("x-constal-tenant",t.tenant);let x;try{x=await s.fetch(g,{method:"GET",headers:j})}catch(N){throw new R(0,L(N instanceof Error?N.message:"network request failed",[t.apiKey]))}if(!x.ok){let N=await q(x);throw new R(x.status,L(te(N),[t.apiKey]),x.headers.get("x-request-id"))}let ne=await q(x);if(y=ne?.data??ne,y?.status==="deployed")return y;if(y?.status==="failed")throw new R(422,y.error??"deployment build failed")}throw new R(408,`deployment ${v} did not finish within ${c} seconds`)}async function St(e,n,t,s){let{options:i}=n;if(e.local==="auth.login"){if(i["token-file"]&&i["token-stdin"])throw new m("Choose only one token source");let r=i["token-file"]?await s.readFile(i["token-file"],"utf8"):i["token-stdin"]?await H(s.stdin):await gt(s,"Constal API key: ");return{authenticated:!0,storedAt:await de(r,{environment:s.environment})}}if(e.local==="auth.logout")return{authenticated:!1,removed:await le({environment:s.environment})};if(e.local==="auth.status")return t.apiKey?(await Oe({method:"GET",route:"/v1/namespaces/{namespace}/agents",bodyKind:void 0},{options:i,values:{}},t,s),{authenticated:!0,credentialSource:t.credentialSource,origin:t.origin,tenant:t.tenant,namespace:t.namespace}):{authenticated:!1,credentialSource:"none",namespace:t.namespace};if(e.local==="context.show")return{origin:t.origin,tenant:t.tenant,namespace:t.namespace,credentialSource:t.credentialSource};if(e.local==="context.use"){if(!["origin","namespace","tenant","clear-tenant"].some(r=>i[r]!==void 0))throw new m("Specify --origin, --namespace, --tenant, or --clear-tenant");return ce({origin:i.origin,namespace:i.namespace,tenant:i.tenant,clearTenant:i["clear-tenant"]},{environment:s.environment})}if(e.local==="deploy.project")return Tt(e,n,t,s);throw new m(`Unsupported local command ${e.local}`)}function Rt(e={}){return{...yt,...e}}async function ke(e,n={}){let t=Rt(n);try{if(!Array.isArray(e))throw new m("argv must be an array");if(e.includes("--version")||e[0]==="version")return $(t.stdout,`${Re}
44
+ `}function vt(e){return[..._].sort((n,t)=>t.path.length-n.path.length).find(n=>n.path.every((t,s)=>e[s]===t))}function bt(e,n){let t={},s=[],i=new Map(Q(e).map(d=>[d.name,d]));for(let d=0;d<n.length;d++){let p=n[d];if(p==="--"){s.push(...n.slice(d+1));break}if(!p.startsWith("--")){s.push(p);continue}let[h,f]=p.slice(2).split(/=(.*)/su,2),w=h.startsWith("no-"),y=w?h.slice(3):h,v=i.get(y);if(!v)throw new m(`Unknown option --${h} for ${G(e)}`);if(v.value){if(w)throw new m(`--no-${y} is not valid`);let b=f??n[++d];if(b===void 0||b.startsWith("--"))throw new m(`--${y} requires a value`);if(v.choices&&!v.choices.includes(b))throw new m(`--${y} must be one of ${v.choices.join(", ")}`);t[y]=v.repeatable?[...t[y]??[],b]:b}else t[y]=!w}let r=e.positionals??[];if(s.length<r.filter(d=>!d.optional).length||s.length>r.length)throw new m(`Expected ${r.map(d=>`<${d.name}>`).join(" ")||"no arguments"}`);let c=Object.fromEntries(r.map((d,p)=>[d.name,s[p]]));for(let d of e.options??[])if(d.required&&t[d.name]===void 0)throw new m(`--${d.name} is required`);return{options:t,values:c}}function je(e){let n={};for(let t of e??[]){let s=String(t).indexOf("="),i=s<0?"":String(t).slice(0,s),r=s<0?"":String(t).slice(s+1);if(!/^[A-Za-z][A-Za-z0-9._-]{0,127}$/u.test(i)||!/^crn:constal:[^\s]{1,1000}$/u.test(r))throw new m("--bind must use NAME=CRN with a valid binding name and Constal Resource CRN");if(Object.hasOwn(n,i)&&n[i]!==r)throw new m(`--bind ${i} was supplied with different Resources`);n[i]=r}return Object.keys(n).length?JSON.stringify(Object.fromEntries(Object.entries(n).sort(([t],[s])=>t.localeCompare(s)))):null}async function wt(e,n,t){if(e!==void 0)return e==="@-"?(await H(n.stdin)).trim():e.startsWith("@")?(await n.readFile(e.slice(1),"utf8")).trim():e}async function U(e,n,t,s){let i=await wt(e,n,t);if(i===void 0)return s;try{return JSON.parse(i)}catch{throw new m(`${t} must be valid JSON, @FILE, or @-`)}}async function A(e,n,t,s){let i=await U(e,n,t,s);if(!i||typeof i!="object"||Array.isArray(i))throw new m(`${t} must be a JSON object`);return i}async function Se(e,n){if(e["material-file"]&&e["material-stdin"])throw new m("Choose only one material source");if(e["material-file"])return(await n.readFile(e["material-file"],"utf8")).replace(/[\r\n]+$/u,"");if(e["material-stdin"])return(await H(n.stdin)).replace(/[\r\n]+$/u,"")}function ee(e,n=[]){if(typeof e=="string")n.push(e);else if(Array.isArray(e))for(let t of e)ee(t,n);else if(e&&typeof e=="object")for(let t of Object.values(e))ee(t,n);return n}async function Et(e,n,t){let{options:s,values:i}=n,r,c=[];switch(e.bodyKind){case void 0:return{body:void 0,headers:{},sensitiveValues:c};case"archive":{let d=await t.readFile(i.archive),p=/\.(?:tar\.gz|tgz)$/iu.test(i.archive);if(!p&&!/\.zip$/iu.test(i.archive))throw new m("Deployment archive must end in .zip, .tar.gz, or .tgz");let h=s["idempotency-key"]??`sha256-${dt("sha256").update(d).digest("hex")}`;return{body:d,headers:{"content-type":p?"application/gzip":"application/zip","idempotency-key":h},sensitiveValues:c}}case"required-json":if(s.body===void 0)throw new m("--body is required");r=await A(s.body,t,"body");break;case"optional-json":r=await A(s.body,t,"body",{});break;case"protected-json":if(s.body===void 0)throw new m("--body is required");if(!s.body.startsWith("@"))throw new m("This setup document must be read from @FILE or @-");r=await A(s.body,t,"body"),c.push(...ee(r));break;case"resource-kind":if(s.body===void 0)throw new m("--body is required");r={...await A(s.body,t,"body"),kind:e.resourceKind};break;case"json":r=await A(s.body,t,"body",{});break;case"reason":r={...s.reason?{reason:s.reason}:{}};break;case"run-start":{r={body:await U(s.data,t,"data",{}),deliver:s.deliver??"queue",...s.tags===void 0?{}:{tags:await A(s.tags,t,"tags",{})}};break}case"wait-resolve":if(s.value===void 0)throw new m("--value is required");r={value:await U(s.value,t,"value")};break;case"steer":r={text:s.text,...s.data===void 0?{}:{data:await U(s.data,t,"data")}};break;case"interrupt":r={...await A(s.body,t,"body",{}),mode:s.mode};break;case"rollout-control":r={deploymentRevision:s.deployment,reason:s.reason};break;case"schedule-delete":r={expectedHash:s["expected-hash"]};break;case"credential-create":{let d=await Se(s,t);r={id:i.credential,provider:s.provider,configuration:await A(s.configuration,t,"configuration",{}),...s.policies===void 0?{}:{policies:await U(s.policies,t,"policies")},...d===void 0?{}:{material:d}},d!==void 0&&c.push(d);break}case"credential-version":{let d=await Se(s,t);if(d===void 0)throw new m("--material-file or --material-stdin is required");c.push(d),r={material:d};break}default:throw new m(`Unsupported request body kind ${e.bodyKind}`)}if(!r||typeof r!="object"||Array.isArray(r))throw new m("Request body must be a JSON object");return e.eventId&&r.eventId===void 0&&(r.eventId=s["event-id"]??t.randomUUID()),{body:JSON.stringify(r),headers:{"content-type":"application/json"},sensitiveValues:c}}function $e(e,n,t){let s={...n.values,namespace:t.namespace},i=e.route.replace(/\{([^}]+)\}/gu,(c,d)=>encodeURIComponent(s[d])),r=new URL(`${t.origin}${i}`);for(let[c,d]of e.query??[])n.options[c]!==void 0&&r.searchParams.set(d,n.options[c]);for(let[c,d]of Object.entries(e.queryValues??{}))r.searchParams.set(c,d);return r}async function q(e){return(e.headers.get("content-type")??"").includes("json")?e.json().catch(()=>null):e.text()}function te(e){return typeof e=="string"?e:typeof e?.error=="string"?e.error:typeof e?.error?.message=="string"?e.error.message:typeof e?.message=="string"?e.message:e==null?"request failed":JSON.stringify(e)}function L(e,n){let t=String(e??"");for(let s of n)s&&(t=t.replaceAll(String(s),"[REDACTED]"));return t}async function Oe(e,n,t,s){if(!t.apiKey)throw new m("No API key is configured. Set CONSTAL_API_KEY or run constal auth login");let i=$e(e,n,t),r=await Et(e,n,s),c=new Headers({authorization:`Bearer ${t.apiKey}`,accept:e.stream?"text/event-stream":"application/json",...r.headers});t.tenant&&c.set("x-constal-tenant",t.tenant),n.options["mastra-storage"]&&c.set("x-constal-mastra-storage",n.options["mastra-storage"]);let d=je(n.options.bind);d&&c.set("x-constal-framework-bindings",d);let p;try{p=await s.fetch(i,{method:e.method,headers:c,...r.body===void 0?{}:{body:r.body}})}catch(h){let f=h instanceof Error?h.message:"network request failed";throw new R(0,L(f,[t.apiKey,...r.sensitiveValues]))}if(!p.ok){let h=await q(p),f=L(te(h),[t.apiKey,...r.sensitiveValues]);throw new R(p.status,f,p.headers.get("x-request-id"))}if(e.stream){if(!p.body)return null;for await(let h of p.body)s.stdout.write(h);return null}if(e.binary){let h=new Uint8Array(await p.arrayBuffer());return n.options.out?(await s.writeFile(n.options.out,h,{mode:384}),n.options.quiet||$(s.stderr,`Wrote ${h.byteLength} bytes to ${n.options.out}
45
+ `)):s.stdout.write(h),null}return q(p)}async function Tt(e,n,t,s){if(!t.apiKey)throw new m("No API key is configured. Set CONSTAL_API_KEY or run constal auth login");let i=n.values.source??".",r;try{r=await ve(i,s.readFile)}catch(g){throw new m(g instanceof Error?g.message:String(g))}let c=n.options.timeout===void 0?600:Number(n.options.timeout);if(!Number.isSafeInteger(c)||c<1||c>3600)throw new m("--timeout must be an integer between 1 and 3600 seconds");let d=$e(e,n,t),p=new Headers({authorization:`Bearer ${t.apiKey}`,accept:"application/json","content-type":r.contentType,"idempotency-key":n.options["idempotency-key"]??r.idempotencyKey,"x-constal-namespace":t.namespace});t.tenant&&p.set("x-constal-tenant",t.tenant),r.projectRoot&&p.set("x-constal-project-root",r.projectRoot),n.options["mastra-storage"]&&p.set("x-constal-mastra-storage",n.options["mastra-storage"]);let h=je(n.options.bind);h&&p.set("x-constal-framework-bindings",h);let f;try{f=await s.fetch(d,{method:"POST",headers:p,body:r.body})}catch(g){throw new R(0,L(g instanceof Error?g.message:"network request failed",[t.apiKey]))}if(!f.ok){let g=await q(f);throw new R(f.status,L(te(g),[t.apiKey]),f.headers.get("x-request-id"))}let w=await q(f),y=w?.data??w,v=y?.deploymentRevision;if(n.options.wait===!1||typeof v!="string"||y.status==="deployed")return y;let b=Date.now()+c*1e3;for(;Date.now()<b;){await new Promise(N=>setTimeout(N,1e3));let g=new URL(`${t.origin}/v1/deployments/${encodeURIComponent(v)}`),j=new Headers({authorization:`Bearer ${t.apiKey}`,accept:"application/json"});t.tenant&&j.set("x-constal-tenant",t.tenant);let x;try{x=await s.fetch(g,{method:"GET",headers:j})}catch(N){throw new R(0,L(N instanceof Error?N.message:"network request failed",[t.apiKey]))}if(!x.ok){let N=await q(x);throw new R(x.status,L(te(N),[t.apiKey]),x.headers.get("x-request-id"))}let ne=await q(x);if(y=ne?.data??ne,y?.status==="deployed")return y;if(y?.status==="failed")throw new R(422,y.error??"deployment build failed")}throw new R(408,`deployment ${v} did not finish within ${c} seconds`)}async function St(e,n,t,s){let{options:i}=n;if(e.local==="auth.login"){if(i["token-file"]&&i["token-stdin"])throw new m("Choose only one token source");let r=i["token-file"]?await s.readFile(i["token-file"],"utf8"):i["token-stdin"]?await H(s.stdin):await gt(s,"Constal API key: ");return{authenticated:!0,storedAt:await de(r,{environment:s.environment})}}if(e.local==="auth.logout")return{authenticated:!1,removed:await le({environment:s.environment})};if(e.local==="auth.status")return t.apiKey?(await Oe({method:"GET",route:"/v1/namespaces/{namespace}/agents",bodyKind:void 0},{options:i,values:{}},t,s),{authenticated:!0,credentialSource:t.credentialSource,origin:t.origin,tenant:t.tenant,namespace:t.namespace}):{authenticated:!1,credentialSource:"none",namespace:t.namespace};if(e.local==="context.show")return{origin:t.origin,tenant:t.tenant,namespace:t.namespace,credentialSource:t.credentialSource};if(e.local==="context.use"){if(!["origin","namespace","tenant","clear-tenant"].some(r=>i[r]!==void 0))throw new m("Specify --origin, --namespace, --tenant, or --clear-tenant");return ce({origin:i.origin,namespace:i.namespace,tenant:i.tenant,clearTenant:i["clear-tenant"]},{environment:s.environment})}if(e.local==="deploy.project")return Tt(e,n,t,s);throw new m(`Unsupported local command ${e.local}`)}function Rt(e={}){return{...yt,...e}}async function Ae(e,n={}){let t=Rt(n);try{if(!Array.isArray(e))throw new m("argv must be an array");if(e.includes("--version")||e[0]==="version")return $(t.stdout,`${Re}
46
46
  `),0;if(!e.length||e[0]==="--help")return $(t.stdout,Te()),0;let s=e[0]==="help",i=s?e.slice(1):e,r=vt(i);if(!r)throw new m(`Unknown command ${i.join(" ")||"(none)"}`);if(s||i.includes("--help"))return $(t.stdout,Te(r)),0;let c=bt(r,i.slice(r.path.length)),d=await ie({environment:t.environment,overrides:c.options}),p=r.local?await St(r,c,d,t):await Oe(r,c,d,t);return p!=null&&$(t.stdout,we(p,c.options.output??"table")),0}catch(s){return $(t.stderr,`Error: ${s instanceof Error?s.message:String(s)}
47
47
  `),s instanceof m&&$(t.stderr,`Run constal --help for usage.
48
- `),Number(s?.exitCode??1)}}process.exitCode=await ke(process.argv.slice(2));
48
+ `),Number(s?.exitCode??1)}}process.exitCode=await Ae(process.argv.slice(2));