@dam-agents/cli 0.2.13 → 0.2.15-rc1

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/dist/bin.js +334 -286
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -26722,12 +26722,38 @@ function date4(params) {
26722
26722
  config(en_default());
26723
26723
 
26724
26724
  // ../api-server-api/src/modules/shared.ts
26725
+ var RESOURCE_NAME_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
26726
+ function resourceNameSchema(example) {
26727
+ return external_exports.string().min(1, "name is required").max(63, "name must be 63 characters or fewer").regex(
26728
+ RESOURCE_NAME_PATTERN,
26729
+ `name must be lowercase letters, digits, and single hyphens (e.g. ${example})`
26730
+ );
26731
+ }
26725
26732
  var ENV_NAME_RE = /^[A-Z_][A-Z0-9_]*$/;
26726
26733
  var envVarSchema = external_exports.object({
26727
26734
  name: external_exports.string().min(1).max(255).regex(ENV_NAME_RE, "name must match [A-Z_][A-Z0-9_]*"),
26728
26735
  value: external_exports.string().max(1e4)
26729
26736
  });
26730
26737
 
26738
+ // ../api-server-api/src/modules/events/schemas.ts
26739
+ var liveEventSchema = external_exports.discriminatedUnion("topic", [
26740
+ external_exports.object({ topic: external_exports.literal("sync") }),
26741
+ external_exports.object({ topic: external_exports.literal("approvals"), agentId: external_exports.string().min(1) }),
26742
+ external_exports.object({ topic: external_exports.literal("agents"), agentId: external_exports.string().min(1) }),
26743
+ external_exports.object({ topic: external_exports.literal("schedules"), agentId: external_exports.string().min(1) }),
26744
+ external_exports.object({ topic: external_exports.literal("harnessConfig"), agentId: external_exports.string().min(1) }),
26745
+ external_exports.object({
26746
+ topic: external_exports.literal("experiments"),
26747
+ experimentId: external_exports.string().min(1),
26748
+ agentId: external_exports.string().min(1)
26749
+ }),
26750
+ external_exports.object({
26751
+ topic: external_exports.literal("artifacts"),
26752
+ artifactId: external_exports.string().min(1).optional(),
26753
+ agentId: external_exports.string().min(1).optional()
26754
+ })
26755
+ ]);
26756
+
26731
26757
  // ../api-server-api/src/modules/skills/schemas.ts
26732
26758
  var skillSourcePathSchema = external_exports.string().transform((p2) => p2.trim().replace(/^\/+|\/+$/g, "")).refine((p2) => !p2.split("/").includes(".."), "path must not contain '..'");
26733
26759
  var skillSourceSchema = external_exports.object({
@@ -26735,12 +26761,7 @@ var skillSourceSchema = external_exports.object({
26735
26761
  name: external_exports.string(),
26736
26762
  gitUrl: external_exports.string(),
26737
26763
  path: external_exports.string().optional(),
26738
- /** True when the source is managed by the cluster admin
26739
- * (Helm-seeded). Users can't delete it. */
26740
26764
  system: external_exports.boolean().optional(),
26741
- /** Present when the source was declared by an agent template
26742
- * (spec.skillSources). UI-only hint for the "Agent" badge —
26743
- * backend treats template sources as read-only. */
26744
26765
  fromTemplate: external_exports.object({ templateId: external_exports.string(), templateName: external_exports.string() }).optional(),
26745
26766
  canPublish: external_exports.boolean().optional()
26746
26767
  });
@@ -26754,57 +26775,39 @@ var skillSchema = external_exports.object({
26754
26775
  description: external_exports.string(),
26755
26776
  version: external_exports.string(),
26756
26777
  contentHash: external_exports.string(),
26757
- /** Repo-relative directory the skill was found in, whichever Source Root it
26758
- * came from — what a raw-file URL needs. Distinct from `skillSourceSchema.path`,
26759
- * which is the source's optional subdir; `dir` is this one skill's actual
26760
- * location under it. Optional: the agent-runtime clone scan (private /
26761
- * non-GitHub sources) doesn't report it. */
26762
26778
  dir: external_exports.string().optional()
26763
26779
  });
26764
26780
  var skillListResultSchema = external_exports.object({
26765
26781
  skills: external_exports.array(skillSchema),
26766
- /** ISO 8601 time the source's skill list was last read from upstream. A
26767
- * cache hit reports the original read, not the moment of the hit. */
26768
- scannedAt: external_exports.string().datetime()
26782
+ scannedAt: external_exports.string().datetime(),
26783
+ visibility: external_exports.enum(["public", "private"]).optional()
26769
26784
  });
26770
26785
  var scanFailureCodes = [
26771
26786
  "needs_github_connection",
26772
26787
  "needs_sandbox",
26773
26788
  "repo_unreachable",
26774
26789
  "agent_unreachable",
26790
+ "source_path_not_found",
26791
+ "source_path_empty",
26775
26792
  "other"
26776
26793
  ];
26777
26794
  var scanFailureSchema = external_exports.object({
26778
26795
  code: external_exports.enum(scanFailureCodes),
26779
- /** Single line naming the cause. */
26780
26796
  title: external_exports.string(),
26781
- /** Single line naming the fix. */
26782
26797
  detail: external_exports.string()
26783
26798
  });
26784
26799
  var skillRefSchema = external_exports.object({
26785
26800
  source: external_exports.string(),
26786
26801
  name: external_exports.string(),
26787
26802
  version: external_exports.string(),
26788
- /** Deterministic SHA-256 of the skill directory's file contents at
26789
- * install time. Compared to the scanner's contentHash to flag drift.
26790
- * Optional for backward compatibility with installs that pre-date
26791
- * this field. */
26792
26803
  contentHash: external_exports.string().optional(),
26793
- /** Source subdir the skill was installed from, denormalized so the apply
26794
- * path resolves the skill dir without re-reading the source. */
26795
26804
  path: external_exports.string().optional()
26796
26805
  });
26797
26806
  var localSkillSchema = external_exports.object({
26798
26807
  name: external_exports.string(),
26799
26808
  description: external_exports.string(),
26800
26809
  skillPath: external_exports.string(),
26801
- /** Provenance vs. the image's pristine copy: shipped untouched, shipped
26802
- * but diverged, or created at runtime. Absent on pre-provenance pods —
26803
- * treat as `user`. */
26804
26810
  origin: external_exports.enum(["system", "system-modified", "user"]).optional(),
26805
- /** Deterministic SHA-256 of the skill directory, comparable with a scanned
26806
- * skill's `contentHash`. Present only for skills the server asked the pod to
26807
- * hash, and absent on pods predating this field (#3019). */
26808
26811
  contentHash: external_exports.string().optional()
26809
26812
  });
26810
26813
  var skillPublishRecordSchema = external_exports.object({
@@ -26813,27 +26816,14 @@ var skillPublishRecordSchema = external_exports.object({
26813
26816
  sourceName: external_exports.string(),
26814
26817
  sourceGitUrl: external_exports.string(),
26815
26818
  prUrl: external_exports.string(),
26816
- /** ISO 8601 timestamp. */
26817
26819
  publishedAt: external_exports.string(),
26818
- /** Resolved outcome of `prUrl`, or null when it has never been
26819
- * resolved — the source is private, the read was rate-limited, the
26820
- * pull request is gone. `merged` and `closed` are terminal and are
26821
- * never re-read (#3019). */
26822
26820
  prState: external_exports.enum(["draft", "open", "merged", "closed"]).nullable(),
26823
- /** ISO 8601 timestamp of the last resolution *attempt*, which is not
26824
- * the same as the last success: an attempt that resolved nothing
26825
- * still stamps it, because it doubles as the backoff clock. Null
26826
- * until the first attempt. */
26827
26821
  prStateCheckedAt: external_exports.string().nullable()
26828
26822
  });
26829
26823
  var skillStateOutputSchema = external_exports.object({
26830
26824
  installed: external_exports.array(skillRefSchema),
26831
26825
  standalone: external_exports.array(localSkillSchema),
26832
26826
  instancePublishes: external_exports.array(skillPublishRecordSchema),
26833
- /** Present only when `standalone` came from a recorded snapshot rather than a
26834
- * live pod read — the sandbox is stopped. Absent while running, which is what
26835
- * lets a reader tell live truth from a snapshot without a second field for
26836
- * the running case. */
26837
26827
  standaloneSnapshot: external_exports.object({ capturedAt: external_exports.string().datetime() }).optional()
26838
26828
  });
26839
26829
  var skillListSourcesInputSchema = external_exports.object({ agentId: external_exports.string().min(1).optional() }).optional();
@@ -26859,9 +26849,6 @@ var skillGetContentInputSchema = external_exports.object({
26859
26849
  });
26860
26850
  var skillContentSchema = external_exports.object({
26861
26851
  content: external_exports.string(),
26862
- /** Source-relative directory the SKILL.md was found in, when resolvable —
26863
- * lets the UI build an accurate blob link instead of guessing the dir from
26864
- * the (frontmatter) skill name. */
26865
26852
  dir: external_exports.string().optional()
26866
26853
  });
26867
26854
  var skillInstallInputSchema = external_exports.object({
@@ -26876,6 +26863,61 @@ var skillUninstallInputSchema = external_exports.object({
26876
26863
  source: external_exports.string().url(),
26877
26864
  name: external_exports.string().min(1)
26878
26865
  });
26866
+ var skillSetEntrySchema = external_exports.object({
26867
+ source: external_exports.string().url(),
26868
+ name: external_exports.string().min(1)
26869
+ });
26870
+ var skillSetNameSchema = resourceNameSchema("my-skill-set");
26871
+ var skillSetSchema = external_exports.object({
26872
+ id: external_exports.string(),
26873
+ name: external_exports.string(),
26874
+ skills: external_exports.array(skillSetEntrySchema),
26875
+ createdAt: external_exports.string()
26876
+ });
26877
+ var skillSetCreateInputSchema = external_exports.object({
26878
+ name: skillSetNameSchema,
26879
+ skills: external_exports.array(skillSetEntrySchema).min(1).max(500)
26880
+ });
26881
+ var skillSetDeleteInputSchema = external_exports.object({ id: external_exports.string().min(1) });
26882
+ var skillSetApplyInputSchema = external_exports.object({
26883
+ agentId: external_exports.string().min(1),
26884
+ setIds: external_exports.array(external_exports.string().min(1)).min(1).max(50)
26885
+ });
26886
+ var skillSetSkipReasonSchema = external_exports.enum([
26887
+ "source-not-connected",
26888
+ "source-unreadable",
26889
+ "not-in-source"
26890
+ ]);
26891
+ var skillSetApplyResultSchema = external_exports.object({
26892
+ installed: external_exports.array(skillRefSchema),
26893
+ added: external_exports.number().int().nonnegative(),
26894
+ skipped: external_exports.array(
26895
+ skillSetEntrySchema.extend({ reason: skillSetSkipReasonSchema })
26896
+ )
26897
+ });
26898
+ var MAX_SKILL_BATCH_ENTRIES = 500;
26899
+ var skillApplyBatchInputSchema = external_exports.object({
26900
+ agentId: external_exports.string().min(1),
26901
+ install: external_exports.array(
26902
+ external_exports.object({
26903
+ source: external_exports.string().url(),
26904
+ name: external_exports.string().min(1),
26905
+ version: external_exports.string().min(1),
26906
+ contentHash: external_exports.string().optional()
26907
+ })
26908
+ ).max(MAX_SKILL_BATCH_ENTRIES).default([]),
26909
+ uninstall: external_exports.array(
26910
+ external_exports.object({
26911
+ source: external_exports.string().url(),
26912
+ name: external_exports.string().min(1)
26913
+ })
26914
+ ).max(MAX_SKILL_BATCH_ENTRIES).default([])
26915
+ }).refine(
26916
+ (v2) => v2.install.length + v2.uninstall.length <= MAX_SKILL_BATCH_ENTRIES,
26917
+ {
26918
+ message: `one batch carries at most ${MAX_SKILL_BATCH_ENTRIES} skills, install and uninstall combined`
26919
+ }
26920
+ );
26879
26921
  var skillListLocalInputSchema = external_exports.object({
26880
26922
  agentId: external_exports.string().min(1)
26881
26923
  });
@@ -26951,6 +26993,7 @@ var templateSpecSchema = external_exports.object({
26951
26993
  category: templateCategorySchema,
26952
26994
  tags: external_exports.array(external_exports.string()).optional(),
26953
26995
  docsUrl: external_exports.string().optional(),
26996
+ releaseNotesUrl: external_exports.string().optional(),
26954
26997
  setupNote: external_exports.object({ title: external_exports.string(), body: external_exports.string() }).optional(),
26955
26998
  experimental: external_exports.boolean().optional(),
26956
26999
  mounts: external_exports.array(mountSchema).optional(),
@@ -26958,14 +27001,7 @@ var templateSpecSchema = external_exports.object({
26958
27001
  env: external_exports.array(envVarConfigMapSchema).optional(),
26959
27002
  resources: resourcesSchema.optional(),
26960
27003
  imagePullPolicy: external_exports.string().optional(),
26961
- // Names a kubernetes.io/dockerconfigjson Secret in the agent namespace,
26962
- // pre-created by the chart for templates that pull from a private registry
26963
- // (e.g. experimental external agents). Carried onto the agent spec so the
26964
- // pod can pull the image without the user entering registry credentials.
26965
27004
  imagePullSecretRef: external_exports.string().optional(),
26966
- // Seeds the created agent's per-agent hibernation override (Go duration):
26967
- // "0s" never hibernates, omitted inherits the chart-wide default. A user's
26968
- // explicit choice at create time still wins over this.
26969
27005
  hibernationTimeout: external_exports.string().optional(),
26970
27006
  storageSize: external_exports.string().optional(),
26971
27007
  backend: external_exports.object({
@@ -26981,13 +27017,9 @@ var templateSpecSchema = external_exports.object({
26981
27017
  var repoSchema = external_exports.object({
26982
27018
  id: external_exports.string().min(1),
26983
27019
  name: external_exports.string().min(1),
26984
- /** HTTPS clone URL (".git" form). Cloned into the work dir at first run. */
26985
27020
  url: external_exports.url(),
26986
- /** Branch or tag to clone; omitted = the repo's default branch. */
26987
27021
  ref: external_exports.string().min(1).optional(),
26988
27022
  description: external_exports.string().optional(),
26989
- /** Template ids this repo is compatible with; the UI filters by the chosen
26990
- * harness. Empty means "offered for no harness". */
26991
27023
  compatibleTemplates: external_exports.array(external_exports.string()).default([])
26992
27024
  });
26993
27025
 
@@ -27000,21 +27032,10 @@ var spawnInvocationRequestSchema = external_exports.object({
27000
27032
  templateId: external_exports.string().min(1).optional(),
27001
27033
  connections: external_exports.array(external_exports.string().min(1)).optional(),
27002
27034
  prompt: external_exports.string().min(1),
27003
- // The result JSON Schema — arbitrary JSON, validated structurally by ajv
27004
- // when the target reports (a malformed schema is rejected at spawn).
27005
27035
  schema: external_exports.unknown(),
27006
- // Optional liveness deadline for this target, in ms. Bounded server-side; a
27007
- // shorter value fails a wedged/misconfigured target fast, a longer one lets
27008
- // a heavy target run past the default hour.
27009
27036
  ttlMs: external_exports.number().int().min(MIN_INVOCATION_TTL_MS).max(MAX_INVOCATION_TTL_MS).optional(),
27010
- // Optional resource limits. A heavy Make (clone + install + build)
27011
- // OOM-kills at the template's small default memory, so let the driver raise
27012
- // it. Same grammar and floors as the agent size knob.
27013
27037
  memory: external_exports.string().regex(/^\d+(Mi|Gi)$/, "memory must look like '512Mi' or '4Gi'").optional(),
27014
27038
  cpu: external_exports.string().regex(/^\d+(\.\d+)?m?$/, "cpu must look like '2', '0.5' or '500m'").optional(),
27015
- // Experiments v2 span attach: "<experimentId>/<spanId>" stamped by the
27016
- // experiment SDK when the spawn happens inside a span, so the Trace Feed
27017
- // shows this invocation under its stage. Opaque to invocations.
27018
27039
  experimentSpanId: external_exports.string().min(1).max(300).optional()
27019
27040
  }).refine((d2) => d2.image !== void 0 || d2.templateId !== void 0, {
27020
27041
  message: "either image or templateId is required"
@@ -27024,7 +27045,8 @@ var spawnInvocationResponseSchema = external_exports.object({
27024
27045
  });
27025
27046
  var invocationViewSchema = external_exports.object({
27026
27047
  status: external_exports.enum(["running", "done", "failed"]),
27027
- result: external_exports.unknown()
27048
+ result: external_exports.unknown(),
27049
+ errorReason: external_exports.string().optional()
27028
27050
  });
27029
27051
 
27030
27052
  // ../agent-runtime-api/src/modules/files/schemas.ts
@@ -27052,9 +27074,6 @@ var fileRemoveInputSchema = external_exports.object({ path: pathSchema });
27052
27074
  var fileUploadInputSchema = external_exports.object({
27053
27075
  path: pathSchema,
27054
27076
  contentBase64: external_exports.string(),
27055
- /** Browser-reported MIME (File.type). Carried in the API for observability
27056
- * and forward-compat; server-side reads still detect MIME from magic
27057
- * bytes so we don't need to persist this. */
27058
27077
  contentType: external_exports.string().max(255).optional(),
27059
27078
  overwrite: external_exports.boolean().optional()
27060
27079
  });
@@ -27081,14 +27100,9 @@ var skillPublishInputSchema2 = external_exports.object({
27081
27100
  repo: external_exports.string().min(1),
27082
27101
  title: external_exports.string().min(1),
27083
27102
  body: external_exports.string(),
27084
- // Source subdir the skill is published into; mirrors the scanner so a
27085
- // subdir source's own scan finds what was published back to it.
27086
27103
  path: external_exports.string().optional()
27087
27104
  });
27088
27105
  var skillListLocalInputSchema2 = external_exports.object({
27089
- /** Names to compute `contentHash` for. Hashing walks the whole skill dir on
27090
- * an NFS-backed PVC and this runs on every state poll, so the caller asks
27091
- * only for the few skills it needs it for (#3019). */
27092
27106
  hashNames: external_exports.array(external_exports.string()).optional()
27093
27107
  });
27094
27108
  var skillReadLocalInputSchema2 = external_exports.object({
@@ -27101,10 +27115,7 @@ var skillReadPullRequestInputSchema = external_exports.object({
27101
27115
  });
27102
27116
  var skillReadSkillFileInputSchema = external_exports.object({
27103
27117
  source: external_exports.string().min(1),
27104
- /** Commit SHA the scan pinned — the preview renders the revision the
27105
- * catalog listed. */
27106
27118
  version: external_exports.string().min(1),
27107
- /** Repo-relative skill directory from the scan; `SKILL.md` is read inside it. */
27108
27119
  dir: external_exports.string().min(1)
27109
27120
  });
27110
27121
  var skillDeleteLocalInputSchema2 = external_exports.object({
@@ -27113,14 +27124,16 @@ var skillDeleteLocalInputSchema2 = external_exports.object({
27113
27124
  var skillWriteLocalInputSchema = external_exports.object({
27114
27125
  skills: external_exports.array(
27115
27126
  external_exports.object({
27116
- /** Confirmed display name — becomes frontmatter `name:`; the dir is its slug. */
27117
27127
  name: external_exports.string().min(1).max(128),
27118
- /** Raw Markdown file content; lands as SKILL.md. */
27119
27128
  content: external_exports.string()
27120
27129
  })
27121
27130
  ).min(1).max(50)
27122
27131
  });
27123
27132
 
27133
+ // ../agent-runtime-api/src/modules/workspace/paths.ts
27134
+ var AGENT_HOME_DIR = "/home/agent";
27135
+ var AGENT_WORK_DIR = `${AGENT_HOME_DIR}/work`;
27136
+
27124
27137
  // ../agent-runtime-api/src/modules/ssh/schemas.ts
27125
27138
  var sshAuthorizeKeyInputSchema = external_exports.object({
27126
27139
  publicKey: external_exports.string().min(1).max(8192).refine((s) => !/[\r\n]/.test(s), "must be a single line")
@@ -27134,10 +27147,6 @@ var backgroundWorkItemSchema = external_exports.object({
27134
27147
  command: advisory(500)
27135
27148
  });
27136
27149
  var backgroundWorkReportSchema = external_exports.object({
27137
- // Also truncated rather than capped, for the same reason: a hold is per
27138
- // session, so one surviving item holds it, whereas rejecting an over-long list
27139
- // would hold nothing at all. Excess entries cost only detail in the status
27140
- // payload.
27141
27150
  items: external_exports.array(backgroundWorkItemSchema).transform((items) => items.slice(0, 64))
27142
27151
  });
27143
27152
 
@@ -27191,17 +27200,10 @@ var egressInjectContribution = external_exports.object({
27191
27200
  headerName: external_exports.string().min(1),
27192
27201
  valueFormat: external_exports.string().min(1),
27193
27202
  encoding: external_exports.literal("basic-x-access-token").optional(),
27194
- // Moves the value into this query param instead of the header; restricted to unreserved chars since the Lua treats it as a trusted literal.
27195
27203
  queryParamName: external_exports.string().regex(/^[A-Za-z0-9_.~-]+$/).optional(),
27196
- // Terminate this host's gateway chain as HTTP/2 so injection lands on a gRPC
27197
- // stream (e.g. Modal's x-modal-token-* metadata). Flows to the injection-hosts
27198
- // annotation the controller reads. Omit for HTTP/1.1 REST hosts.
27199
27204
  http2: external_exports.boolean().optional(),
27200
27205
  port: egressPort,
27201
- // Tunnel WebSocket/SPDY upgrades (kubectl streaming); keeps the chain h1.
27202
27206
  upgrades: external_exports.boolean().optional(),
27203
- // Validate the upstream against the CA in the connection Secret, not the
27204
- // system store (self-signed cluster CAs).
27205
27207
  upstreamCa: external_exports.boolean().optional()
27206
27208
  });
27207
27209
  var fileContribution = external_exports.object({
@@ -27257,7 +27259,6 @@ var scheduleResetEvent = external_exports.object({
27257
27259
  });
27258
27260
  var workspaceSeedEventPayload = external_exports.object({
27259
27261
  url: external_exports.string().min(1),
27260
- /** Branch or tag to clone; omitted = the repo's default branch. */
27261
27262
  ref: external_exports.string().min(1).optional()
27262
27263
  });
27263
27264
  var workspaceSeedEvent = external_exports.object({
@@ -27315,18 +27316,14 @@ var harnessConfigChoice = external_exports.object({
27315
27316
  description: external_exports.string().optional()
27316
27317
  });
27317
27318
  var harnessConfigOptionGroup = external_exports.object({
27318
- // "model", "mode", or a configOption id (e.g. "effort").
27319
27319
  id: external_exports.string().min(1),
27320
27320
  name: external_exports.string().min(1),
27321
27321
  description: external_exports.string().optional(),
27322
- // ACP-style category: "model" | "mode" | "thought_level" | …
27323
27322
  category: external_exports.string().min(1),
27324
27323
  choices: external_exports.array(harnessConfigChoice)
27325
27324
  });
27326
27325
  var harnessConfigCatalog = external_exports.object({
27327
27326
  options: external_exports.array(harnessConfigOptionGroup),
27328
- // Per-model validity: allowed choice values per gated group. Model absent =
27329
- // all allowed; empty array = group hidden for that model (e.g. Haiku effort).
27330
27327
  modelConstraints: external_exports.record(external_exports.string().min(1), external_exports.record(external_exports.string().min(1), external_exports.array(external_exports.string()))).optional()
27331
27328
  });
27332
27329
  var harnessConfigCurrent = external_exports.object({
@@ -27338,10 +27335,7 @@ var harnessConfigCurrent = external_exports.object({
27338
27335
  var capabilities = external_exports.object({
27339
27336
  contributions: external_exports.array(contributionKind),
27340
27337
  events: external_exports.array(eventKind),
27341
- // Whether the harness declares a config mapping (gates the UI panel). Optional
27342
- // for forward-compat with agents that predate it.
27343
27338
  harnessConfig: external_exports.boolean().optional(),
27344
- // The option catalog from the harness's manifest (absent → UI hides the panel).
27345
27339
  harnessConfigCatalog: harnessConfigCatalog.optional()
27346
27340
  });
27347
27341
  var stateSlice = external_exports.object({
@@ -27358,19 +27352,14 @@ var driverFailure = external_exports.object({
27358
27352
  message: external_exports.string().min(1)
27359
27353
  });
27360
27354
  var applyStateResult = external_exports.discriminatedUnion("status", [
27361
- // Processed: resulting cursor + any per-driver failures (empty on a fully clean apply).
27362
27355
  external_exports.object({
27363
27356
  status: external_exports.literal("ok"),
27364
27357
  appliedVersion: external_exports.number().int().nonnegative(),
27365
27358
  appliedHash: external_exports.string().min(1).nullable(),
27366
- // null until the first clean settle
27367
27359
  failures: external_exports.array(driverFailure).default([]),
27368
27360
  settledEvents: external_exports.array(external_exports.string()).default([]),
27369
- // Absent from a pod predating this, or one whose manifest declares no
27370
- // harness-config driver — the server then keeps whatever it holds.
27371
27361
  harnessConfigCurrent: harnessConfigCurrent.optional()
27372
27362
  }),
27373
- // Contributions already at ≥ the requested version; worker reconciles. Events still apply (own version) — settledEvents reports which.
27374
27363
  external_exports.object({
27375
27364
  status: external_exports.literal("stale"),
27376
27365
  appliedVersion: external_exports.number().int().nonnegative(),
@@ -27384,10 +27373,6 @@ var helloInput = external_exports.object({
27384
27373
  protocolVersion: external_exports.literal("v1"),
27385
27374
  agentRuntimeVersion: external_exports.string(),
27386
27375
  capabilities,
27387
- // The config file as it stands at boot, with no discovered model list: `hello`
27388
- // is what delivers capabilities, and the worker won't dispatch an apply until
27389
- // they land, so waiting on the provider here delays the first apply after
27390
- // every boot and wake. The apply reply carries the list instead.
27391
27376
  harnessConfigCurrent: harnessConfigCurrent.optional()
27392
27377
  });
27393
27378
  var helloResult = external_exports.object({
@@ -27419,22 +27404,12 @@ var harnessConfigSnapshotSchema = external_exports.object({
27419
27404
  model: external_exports.string().nullable(),
27420
27405
  mode: external_exports.string().nullable(),
27421
27406
  configOptions: agentConfigOptionsSchema,
27422
- /** Models the provider offered when it was last successfully asked; null when
27423
- * the harness declares no discovery source. A failed attempt leaves this
27424
- * alone, so it can be older than the rest of the snapshot. */
27425
27407
  availableModels: external_exports.array(harnessConfigChoice).nullable(),
27426
27408
  capturedAt: external_exports.string().datetime(),
27427
- /** The model that was in effect when `availableModels` was observed. Comparing
27428
- * the two is only meaningful while this still equals `model`: a model changed
27429
- * since the list was read proves nothing about whether the provider offers it.
27430
- * Absent on rows written before this field existed — treat as unpaired. */
27431
27409
  modelAtDiscovery: external_exports.string().nullable().optional(),
27432
- /** False while the only source is an apply the pod has not reported back. */
27433
27410
  confirmed: external_exports.boolean()
27434
27411
  });
27435
27412
  var harnessConfigSnapshotResultSchema = external_exports.object({
27436
- /** The agent has sent `hello` at least once, so a snapshot is possible.
27437
- * False means "never run" — genuinely nothing to show, not a miss. */
27438
27413
  hasRun: external_exports.boolean(),
27439
27414
  snapshot: harnessConfigSnapshotSchema.nullable()
27440
27415
  });
@@ -27455,7 +27430,6 @@ var egressRuleCurrentPresetInputSchema = external_exports.object({
27455
27430
  var egressRuleCreateInputSchema = external_exports.object({
27456
27431
  agentId: external_exports.string().min(1),
27457
27432
  host: egressHostSchema,
27458
- // Upstream port; omit for 443. Promotes the host onto the L7 chain.
27459
27433
  port: external_exports.number().int().min(1).max(65535).optional(),
27460
27434
  method: external_exports.string().min(1).default("*"),
27461
27435
  pathPattern: external_exports.string().min(1).default("*"),
@@ -27467,6 +27441,9 @@ var egressRuleUpdateInputSchema = external_exports.object({
27467
27441
  pathPattern: external_exports.string().min(1).optional(),
27468
27442
  verdict: ruleVerdictSchema.optional()
27469
27443
  });
27444
+ var egressRuleGetInputSchema = external_exports.object({
27445
+ id: external_exports.string().min(1)
27446
+ });
27470
27447
  var egressRuleRevokeInputSchema = external_exports.object({
27471
27448
  id: external_exports.string().min(1)
27472
27449
  });
@@ -27515,38 +27492,12 @@ var agentCreateInputSchema = external_exports.object({
27515
27492
  password: external_exports.string().min(1)
27516
27493
  }).optional(),
27517
27494
  egressPreset: egressPresetSchema.optional(),
27518
- // Per-agent idle timeout override in minutes (0 = never hibernate); omit to inherit the global default.
27519
27495
  hibernationTimeoutMin: external_exports.number().int().min(0).optional(),
27520
- // Optional: clone this public repo (optionally a branch/tag via `ref`) into
27521
- // the work dir once, via a one-shot `workspace-seed` event. Not enforced
27522
- // against the `gitRepos` catalog server-side — the clone runs in the
27523
- // egress-gated agent pod, so this reaches no URL the agent couldn't already
27524
- // reach itself.
27525
27496
  gitRepo: external_exports.object({ url: external_exports.url(), ref: external_exports.string().min(1).optional() }).optional(),
27526
- // Initial connection grants, settled into the spec at create so credentials
27527
- // ride the first snapshot and the gateway renders its chains once (no
27528
- // readiness flap).
27529
27497
  connectionIds: external_exports.array(external_exports.string()).optional(),
27530
- // The agent's size (#1900): CPU/memory limits, the user-facing "power"
27531
- // knob the Budget bounds (the UI renders it as sliders). Omitted
27532
- // dimensions inherit the template's limits, else the chart default.
27533
- // Requests are derived server-side — never a user concept. Floors match
27534
- // the chart's derivation floors; the budget gate is the only ceiling.
27535
27498
  size: agentSizeSchema.optional(),
27536
- // Sweepable (#2816): mark this agent for automatic deletion by the Agent
27537
- // Sweep once it hibernates. Set on ephemeral agents (Invocation targets);
27538
- // durable owned agents omit it. Stamped as an annotation at create.
27539
27499
  sweepable: external_exports.boolean().optional(),
27540
- // Agent Lifetime (#2816): optional grace in ms a Sweepable agent may stay
27541
- // hibernated before the Sweep deletes it. Default zero — deleted as soon
27542
- // as it hibernates. Ignored unless `sweepable`.
27543
27500
  lifetimeMs: external_exports.number().int().min(0).optional()
27544
- // Agent Kind is deliberately NOT part of this schema: it is a
27545
- // service-level field (see AgentCreateInput) set only by an owning module's
27546
- // create path (knowledge-bases, experiments). A `kind` passed to the public
27547
- // agents.create is stripped, so a caller cannot mint a marked agent that
27548
- // skipped that module's setup — a KB or experiment sandbox whose Install
27549
- // Command never ran.
27550
27501
  }).refine((d2) => d2.templateId !== void 0 || d2.image !== void 0, {
27551
27502
  message: "Either templateId or image is required"
27552
27503
  });
@@ -27556,17 +27507,12 @@ var agentUpdateInputSchema = external_exports.object({
27556
27507
  description: external_exports.string().optional(),
27557
27508
  env: external_exports.array(envVarSchema).max(64).optional(),
27558
27509
  secretRef: external_exports.string().optional(),
27559
- // Per-agent idle timeout override in minutes (0 = never hibernate); null clears it back to the global default.
27560
27510
  hibernationTimeoutMin: external_exports.number().int().min(0).nullable().optional(),
27561
- // Resize (#1900). On a sleeping sandbox the new Size rides the next start
27562
- // through the budget gate; on a running one the increase is gated
27563
- // server-side and the pod restarts to apply it.
27564
27511
  size: agentSizeSchema.optional()
27565
27512
  });
27566
27513
  var agentConnectSlackInputSchema = external_exports.object({
27567
27514
  id: external_exports.string().min(1),
27568
27515
  slackChannelId: external_exports.string().min(1),
27569
- // Ambient mode; absent = off. Mutable: re-connecting updates it in place.
27570
27516
  ambient: external_exports.boolean().optional()
27571
27517
  });
27572
27518
  var agentListTelegramChatsInputSchema = external_exports.object({
@@ -27578,12 +27524,10 @@ var agentUnbindTelegramChatInputSchema = external_exports.object({
27578
27524
  });
27579
27525
  var agentBindTelegramChatInputSchema = external_exports.object({
27580
27526
  agentId: external_exports.string().min(1),
27581
- // Opaque bind-flow id minted by the Telegram OAuth callback.
27582
27527
  flowId: external_exports.string().min(1)
27583
27528
  });
27584
27529
  var agentBindSlackChannelInputSchema = external_exports.object({
27585
27530
  agentId: external_exports.string().min(1),
27586
- // Opaque bind-flow id minted by the Slack in-chat bind OAuth callback.
27587
27531
  flowId: external_exports.string().min(1)
27588
27532
  });
27589
27533
 
@@ -27596,6 +27540,7 @@ var quietWindowSchema = external_exports.object({
27596
27540
  }).refine((w3) => w3.startTime !== w3.endTime, {
27597
27541
  message: "startTime and endTime must differ"
27598
27542
  });
27543
+ var scheduleListForOwnerInputSchema = external_exports.object({ limit: external_exports.number().int().positive().max(200).optional() }).optional();
27599
27544
  var scheduleListInputSchema = external_exports.object({
27600
27545
  agentId: external_exports.string().min(1)
27601
27546
  });
@@ -27683,15 +27628,15 @@ var skeletonSchema = external_exports.object({
27683
27628
  stages: external_exports.array(
27684
27629
  external_exports.object({
27685
27630
  id: stageIdSchema,
27686
- /** Stage ids this stage runs after (edges of the graph). */
27687
- after: external_exports.array(stageIdSchema).max(20).default([])
27631
+ after: external_exports.array(stageIdSchema).max(20).default([]),
27632
+ description: external_exports.string().trim().min(1).max(300).optional()
27688
27633
  })
27689
27634
  ).max(50).default([]),
27690
27635
  loops: external_exports.array(
27691
27636
  external_exports.object({
27692
27637
  id: stageIdSchema,
27693
- /** Member stages, iterated together. */
27694
- stages: external_exports.array(stageIdSchema).min(1).max(50)
27638
+ stages: external_exports.array(stageIdSchema).min(1).max(50),
27639
+ description: external_exports.string().trim().min(1).max(300).optional()
27695
27640
  })
27696
27641
  ).max(10).default([])
27697
27642
  });
@@ -27699,15 +27644,10 @@ var planRegisterRequestSchema = external_exports.object({
27699
27644
  name: external_exports.string().trim().min(1).max(200),
27700
27645
  skeleton: skeletonSchema,
27701
27646
  script: external_exports.object({
27702
- /** Pod-local path the harness will execute (`python <path>`). */
27703
27647
  path: external_exports.string().min(1).max(1024),
27704
27648
  sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
27705
27649
  content: external_exports.string().max(SCRIPT_CONTENT_MAX_BYTES)
27706
27650
  }),
27707
- /** Bespoke dashboard HTML captured like the script (the SDK's
27708
- * dashboard_path): the platform creates or re-versions the draft's
27709
- * dashboard artifact from it. Omitted = keep the existing dashboard, or
27710
- * attach the stock one on first registration. */
27711
27651
  dashboard: external_exports.object({ content: external_exports.string().max(DASHBOARD_CONTENT_MAX_BYTES) }).optional()
27712
27652
  });
27713
27653
  var planRegisterResponseSchema = external_exports.object({
@@ -27734,9 +27674,7 @@ var spanEndEventSchema = external_exports.object({
27734
27674
  type: external_exports.literal("span-end"),
27735
27675
  spanId: spanIdSchema,
27736
27676
  status: external_exports.enum(["ok", "error"]),
27737
- /** Opaque by covenant: captured and charted, never normalized or ranked. */
27738
27677
  score: external_exports.number().finite().optional(),
27739
- /** Artifact Library ids this span produced (candidates, reports). */
27740
27678
  artifactIds: external_exports.array(external_exports.string().min(1)).max(20).optional(),
27741
27679
  attrs: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
27742
27680
  ts: isoTimestampSchema
@@ -27744,7 +27682,6 @@ var spanEndEventSchema = external_exports.object({
27744
27682
  var customDataEventSchema = external_exports.object({
27745
27683
  type: external_exports.literal("custom-data"),
27746
27684
  data: external_exports.record(external_exports.string(), external_exports.unknown()),
27747
- /** false replaces the blob instead of shallow-merging into it. */
27748
27685
  merge: external_exports.boolean().optional()
27749
27686
  });
27750
27687
  var heartbeatEventSchema = external_exports.object({
@@ -27797,8 +27734,6 @@ var knowledgeBaseCreateInputSchema = external_exports.object({
27797
27734
  connectionIds: external_exports.array(external_exports.string()).optional(),
27798
27735
  egressPreset: egressPresetSchema.optional(),
27799
27736
  size: agentSizeSchema.optional(),
27800
- // Which installation procedure to bootstrap the agent with. Defaults to
27801
- // the sole current template so older callers keep working.
27802
27737
  kbTemplateId: knowledgeBaseTemplateIdSchema.default("llm-wiki")
27803
27738
  }).refine((d2) => d2.templateId !== void 0 || d2.image !== void 0, {
27804
27739
  message: "Either templateId or image is required"
@@ -27814,7 +27749,8 @@ var artifactKindSchema = external_exports.enum([
27814
27749
  "binary"
27815
27750
  ]);
27816
27751
  var artifactVisibilitySchema = external_exports.enum(["private", "public"]);
27817
- var titleSchema = external_exports.string().trim().min(1, "title is required").max(300);
27752
+ var ARTIFACT_TITLE_MAX_LENGTH = 300;
27753
+ var titleSchema = external_exports.string().trim().min(1, "title is required").max(ARTIFACT_TITLE_MAX_LENGTH);
27818
27754
  var fileNameSchema = external_exports.string().trim().min(1).max(255);
27819
27755
  var expiresInHoursSchema = external_exports.number().int().positive().max(24 * 365 * 10);
27820
27756
  var artifactIdInputSchema = external_exports.object({ id: external_exports.string().min(1) });
@@ -30964,7 +30900,7 @@ function bobEnvMappings(pins = {}) {
30964
30900
  push("BOB_SHELL_MODEL", pins.model);
30965
30901
  push("BOB_INSTANCE_ID", pins.agentId);
30966
30902
  push("BOB_TEAM_ID", pins.teamId);
30967
- push("BOB_MAX_COINS", pins.maxCoins);
30903
+ push("BOB_MAX_COINS", pins.maxCost);
30968
30904
  push("BOB_CHAT_MODE", pins.chatMode);
30969
30905
  return out;
30970
30906
  }
@@ -31019,7 +30955,6 @@ var PROVIDERS = {
31019
30955
  id: "openai",
31020
30956
  displayName: "OpenAI",
31021
30957
  hostPattern: "api.openai.com",
31022
- // Scope injection to /v1/* so other host endpoints don't get a stray Authorization header.
31023
30958
  pathPattern: "/v1/*",
31024
30959
  modes: [
31025
30960
  {
@@ -31040,7 +30975,6 @@ var PROVIDERS = {
31040
30975
  label: "API Key",
31041
30976
  templateId: "bob",
31042
30977
  defaultEnvMappings: bobEnvMappings(),
31043
- // `Apikey` prefix; `Bearer` would trigger JWT auth.
31044
30978
  injection: {
31045
30979
  headerName: "Authorization",
31046
30980
  valueFormat: "Apikey {value}"
@@ -31087,7 +31021,6 @@ var secretRef = external_exports.object({
31087
31021
  var connectionCategory = external_exports.enum(["app", "mcp", "other"]);
31088
31022
  var refreshBackoff = external_exports.object({
31089
31023
  failures: external_exports.number().int(),
31090
- /** Epoch seconds; ticks before this skip the connection. */
31091
31024
  nextAttempt: external_exports.number().int()
31092
31025
  });
31093
31026
  var oauthAuth = external_exports.object({
@@ -31101,8 +31034,6 @@ var oauthAuth = external_exports.object({
31101
31034
  clientSecretRef: secretRef.optional(),
31102
31035
  expiresAt: external_exports.number().int().optional(),
31103
31036
  connectedAt: external_exports.number().int().optional(),
31104
- // Epoch seconds, set only on a *permanent* token rejection: derives
31105
- // `expired` and parks the connection. Any successful token write clears it.
31106
31037
  refreshFailedAt: external_exports.number().int().optional(),
31107
31038
  refreshBackoff: refreshBackoff.optional(),
31108
31039
  tokenEndpointAcceptJson: external_exports.boolean().optional(),
@@ -31138,17 +31069,8 @@ var githubAppAuth = external_exports.object({
31138
31069
  refreshFailedAt: external_exports.number().int().optional(),
31139
31070
  refreshBackoff: refreshBackoff.optional(),
31140
31071
  host: external_exports.string().min(1).optional(),
31141
- // Optional narrowing of the minted token, stored because every re-mint must
31142
- // ask for the same subset — a scope kept only on the create input would widen
31143
- // back to the whole installation at the first renewal. Absent means the
31144
- // installation's full authority, which is what every connection made before
31145
- // this field existed carries.
31146
31072
  repositories: external_exports.array(external_exports.string().min(1)).nonempty().optional(),
31147
31073
  permissions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
31148
- // Repositories named by GitHub's numeric id rather than by name — what the
31149
- // picker records, since an id survives a rename where a name would start
31150
- // failing at the next renewal. Only one of the two reaches GitHub; ids win
31151
- // when both are set, and connections predating the picker carry names only.
31152
31074
  repositoryIds: external_exports.array(external_exports.number().int()).nonempty().optional()
31153
31075
  });
31154
31076
  var headerAuth = external_exports.object({
@@ -31202,13 +31124,7 @@ var connectionView = external_exports.object({
31202
31124
  hosts: external_exports.array(external_exports.string()),
31203
31125
  host: external_exports.string().min(1).optional(),
31204
31126
  appSlug: external_exports.string().min(1).optional(),
31205
- // Only for an OAuth connection storing its own client secret — an
31206
- // operator-supplied one is deploy config, not replaceable per connection.
31207
31127
  hasClientSecret: external_exports.boolean().optional(),
31208
- // The narrowing a github-app connection currently mints against, so it can
31209
- // be shown and edited rather than only set once at create. Absent means the
31210
- // installation's full authority. Carries no secret — names, ids, and levels
31211
- // are all things the user chose.
31212
31128
  githubAppScope: external_exports.object({
31213
31129
  repositories: external_exports.array(external_exports.string()).optional(),
31214
31130
  repositoryIds: external_exports.array(external_exports.number().int()).optional(),
@@ -31225,13 +31141,10 @@ var templateInput = external_exports.object({
31225
31141
  state: templateInputState,
31226
31142
  presetValue: external_exports.string().optional(),
31227
31143
  secret: external_exports.boolean().optional(),
31228
- // Renders as a multi-line textarea rather than a single-line input (e.g. a PEM private key).
31229
31144
  multiline: external_exports.boolean().optional(),
31230
- // Marks a config input the form packs into `configInputs` rather than the typed auth fields.
31231
31145
  configInput: external_exports.boolean().optional(),
31232
31146
  label: external_exports.string().optional(),
31233
31147
  hint: external_exports.string().optional(),
31234
- // Validation a config input declares, surfaced so clients can validate before submit (the server enforces the same).
31235
31148
  pattern: external_exports.string().optional(),
31236
31149
  patternHint: external_exports.string().optional(),
31237
31150
  enumValues: external_exports.array(external_exports.string()).optional()
@@ -31271,8 +31184,6 @@ var connectionStartOAuthInputSchema = external_exports.object({
31271
31184
  /^\/(?!\/)/,
31272
31185
  "returnTo must be a relative path starting with a single /"
31273
31186
  ).optional(),
31274
- // When set, the callback returns a page that postMessages the result to the
31275
- // opener and closes, instead of redirecting. Used by the popup OAuth flow.
31276
31187
  popup: external_exports.boolean().optional()
31277
31188
  });
31278
31189
  var connectionDiscoverMcpInputSchema = external_exports.object({
@@ -31288,10 +31199,7 @@ var connectionSetAgentConnectionsInputSchema = external_exports.object({
31288
31199
  agentId: external_exports.string().min(1),
31289
31200
  connectionIds: external_exports.array(external_exports.string().min(1))
31290
31201
  });
31291
- var connectionNameSchema = external_exports.string().min(1, "name is required").max(63, "name must be 63 characters or fewer").regex(
31292
- /^[a-z0-9]+(-[a-z0-9]+)*$/,
31293
- "name must be lowercase letters, digits, and single hyphens (e.g. my-mcp-server)"
31294
- );
31202
+ var connectionNameSchema = resourceNameSchema("my-mcp-server");
31295
31203
  var commonFields = {
31296
31204
  templateId: external_exports.string().min(1),
31297
31205
  name: connectionNameSchema
@@ -31315,24 +31223,17 @@ var headerCreateInput = external_exports.object({
31315
31223
  /^[A-Za-z_][A-Za-z0-9_]*$/,
31316
31224
  "env var name must be letters, digits, and underscores (not starting with a digit)"
31317
31225
  ).optional(),
31318
- // Values for the template's declared config inputs, keyed by input name.
31319
31226
  configInputs: external_exports.record(external_exports.string(), external_exports.string()).optional(),
31320
31227
  value: external_exports.string().min(1),
31321
- // Upstream CA bundle for hosts whose TLS cert a public root can't verify
31322
- // (self-signed cluster CAs). PEM, or base64 of PEM (kubeconfig
31323
- // `certificate-authority-data`).
31324
31228
  caData: external_exports.string().optional()
31325
31229
  });
31326
31230
  var clientCredentialsCreateInput = external_exports.object({
31327
31231
  ...commonFields,
31328
31232
  authKind: external_exports.literal("client-credentials"),
31329
31233
  host: external_exports.string().min(1).optional(),
31330
- // The token endpoint is discovered from the issuer's OAuth metadata.
31331
31234
  issuerUrl: external_exports.string().url().optional(),
31332
31235
  clientId: external_exports.string().min(1).optional(),
31333
31236
  clientSecret: external_exports.string().min(1).optional(),
31334
- // Space- or comma-separated; the server splits. A single string keeps the
31335
- // schema-driven forms all-string.
31336
31237
  scopes: external_exports.string().optional(),
31337
31238
  audience: external_exports.string().min(1).optional(),
31338
31239
  headerName: external_exports.string().min(1).optional(),
@@ -31349,14 +31250,8 @@ var githubAppCreateInput = external_exports.object({
31349
31250
  appId: external_exports.string().min(1),
31350
31251
  installationId: external_exports.string().min(1),
31351
31252
  privateKey: external_exports.string().min(1),
31352
- // Optional narrowing of the minted token. Space- or comma-separated; the
31353
- // server parses both. Single strings keep the schema-driven forms all-string,
31354
- // as client-credentials `scopes` does. Blank leaves the token with the
31355
- // installation's full authority.
31356
31253
  repositories: external_exports.string().optional(),
31357
31254
  permissions: external_exports.string().optional(),
31358
- // Repository ids, as picked from the installation. Same all-string shape as
31359
- // the sibling fields; ids take precedence over names when both arrive.
31360
31255
  repositoryIds: external_exports.string().optional()
31361
31256
  });
31362
31257
  var connectionProbeGitHubAppInputSchema = external_exports.object({
@@ -31379,8 +31274,6 @@ var noneCreateInput = external_exports.object({
31379
31274
  ...commonFields,
31380
31275
  authKind: external_exports.literal("none"),
31381
31276
  url: external_exports.string().url().optional(),
31382
- // Optional header credential (API key) for MCP servers guarded by a
31383
- // static header — injected at the gateway, never written to harness config.
31384
31277
  headerName: external_exports.string().min(1).optional(),
31385
31278
  value: external_exports.string().min(1).optional()
31386
31279
  });
@@ -31402,7 +31295,6 @@ var SessionType = {
31402
31295
  ChannelSlack: "channel_slack",
31403
31296
  ChannelTelegram: "channel_telegram",
31404
31297
  ScheduleCron: "schedule_cron",
31405
- /** The turn that launches an experiment script (Execute on a draft). */
31406
31298
  ExperimentExecute: "experiment_execute"
31407
31299
  };
31408
31300
  var SessionMode = /* @__PURE__ */ ((SessionMode2) => {
@@ -31502,7 +31394,7 @@ function describeApprovalPayload(payload) {
31502
31394
  // ../api-server-api/src/modules/egress-rules/format.ts
31503
31395
  function formatEgressRuleSource(source) {
31504
31396
  if (source === "manual") return "manual";
31505
- if (source === "inbox") return "from inbox";
31397
+ if (source === "inbox") return "from an approval";
31506
31398
  if (source === "preset:trusted") return "preset: trusted";
31507
31399
  if (source === "preset:all") return "preset: all";
31508
31400
  if (source.startsWith("connection:")) {
@@ -31528,6 +31420,32 @@ function stripTrailingSlashes(s) {
31528
31420
  return s.slice(0, end);
31529
31421
  }
31530
31422
 
31423
+ // ../api-server-api/src/modules/egress-rules/promotion.ts
31424
+ function needsL7Promotion(method, pathPattern, port) {
31425
+ return method !== "*" || pathPattern !== "*" || port != null;
31426
+ }
31427
+ function promotedHosts(rules) {
31428
+ const hosts = rules.filter((r) => r.host !== "*").filter((r) => !r.source.startsWith("connection:")).filter((r) => needsL7Promotion(r.method, r.pathPattern, r.port)).map((r) => r.host);
31429
+ return [...new Set(hosts)].sort();
31430
+ }
31431
+ function gatewayRestartImpact(input) {
31432
+ const removed = new Set(input.removeIds ?? []);
31433
+ const before = promotedHosts(input.current);
31434
+ const after = promotedHosts([
31435
+ ...input.current.filter((r) => !removed.has(r.id)),
31436
+ ...input.adds ?? []
31437
+ ]);
31438
+ const beforeSet = new Set(before);
31439
+ const afterSet = new Set(after);
31440
+ const promoted = after.filter((h2) => !beforeSet.has(h2));
31441
+ const demoted = before.filter((h2) => !afterSet.has(h2));
31442
+ return {
31443
+ promoted,
31444
+ demoted,
31445
+ willRestart: promoted.length > 0 || demoted.length > 0
31446
+ };
31447
+ }
31448
+
31531
31449
  // ../api-server-api/src/modules/acp/types.ts
31532
31450
  var platformTurnEndedParamsSchema = external_exports.object({
31533
31451
  sessionId: external_exports.string().min(1)
@@ -31537,10 +31455,12 @@ var platformTurnEndedNotificationSchema = external_exports.object({
31537
31455
  method: external_exports.literal("platform/turnEnded"),
31538
31456
  params: platformTurnEndedParamsSchema
31539
31457
  });
31458
+ var platformClippedReplayMetaSchema = external_exports.object({
31459
+ older: external_exports.string().min(1).optional()
31460
+ });
31540
31461
  var platformPromptAcceptedParamsSchema = external_exports.object({
31541
31462
  sessionId: external_exports.string().min(1),
31542
31463
  promptId: external_exports.string().min(1),
31543
- /** True when the prompt was parked behind an in-flight turn. */
31544
31464
  queued: external_exports.boolean()
31545
31465
  });
31546
31466
  var platformPromptAcceptedNotificationSchema = external_exports.object({
@@ -31563,6 +31483,7 @@ var brandSchema = external_exports.object({
31563
31483
  name: external_exports.string(),
31564
31484
  short: external_exports.string(),
31565
31485
  title: external_exports.string(),
31486
+ vendor: external_exports.string(),
31566
31487
  theme: external_exports.object({
31567
31488
  light: external_exports.object({
31568
31489
  accent: external_exports.string(),
@@ -31577,6 +31498,16 @@ var brandSchema = external_exports.object({
31577
31498
  })
31578
31499
  });
31579
31500
 
31501
+ // ../api-server-api/src/modules/agents/public-agent.ts
31502
+ var publicAgentViewSchema = external_exports.object({
31503
+ agentId: external_exports.string(),
31504
+ name: external_exports.string(),
31505
+ ownerName: external_exports.string().nullable()
31506
+ });
31507
+ var publicAgentResponseSchema = external_exports.object({
31508
+ agent: publicAgentViewSchema.nullable()
31509
+ });
31510
+
31580
31511
  // ../api-server-api/src/modules/terms/schemas.ts
31581
31512
  var termsCurrentSchema = external_exports.object({
31582
31513
  version: external_exports.string().min(1),
@@ -31601,6 +31532,16 @@ var termsLatestAcceptanceSchema = external_exports.object({
31601
31532
  acceptedAt: external_exports.date()
31602
31533
  }).nullable();
31603
31534
 
31535
+ // ../api-server-api/src/modules/usage/schemas.ts
31536
+ var entryPointChoiceSchema = external_exports.enum([
31537
+ "sandbox",
31538
+ "experiment",
31539
+ "knowledge-base"
31540
+ ]);
31541
+ var entryPointChosenInputSchema = external_exports.object({
31542
+ choice: entryPointChoiceSchema
31543
+ });
31544
+
31604
31545
  // ../api-server-api/src/modules/auth/types.ts
31605
31546
  var authConfigSchema = external_exports.object({
31606
31547
  issuer: external_exports.string().url(),
@@ -31667,7 +31608,6 @@ var slackFireMentionInputSchema = external_exports.object({
31667
31608
  ts: external_exports.string().min(1),
31668
31609
  threadTs: external_exports.string().optional(),
31669
31610
  text: external_exports.string(),
31670
- /** Workspace id; present so the fake exercises the live-streaming path. */
31671
31611
  teamId: external_exports.string().optional()
31672
31612
  }).strict();
31673
31613
  var slackFireCommandInputSchema = external_exports.object({
@@ -31999,6 +31939,11 @@ hint: ${hint}
31999
31939
  function formatTransportError(reason, host) {
32000
31940
  return `cannot reach server \`${host}\`: ${reason}`;
32001
31941
  }
31942
+ function serverDetail(e2) {
31943
+ if (!(e2 instanceof TRPCClientError)) return "";
31944
+ const code = e2.data?.code;
31945
+ return e2.message && e2.message !== code ? e2.message : "";
31946
+ }
32002
31947
  function printServiceError(error51, host, env = process.env) {
32003
31948
  if (error51.kind === "auth-required") {
32004
31949
  process.stderr.write(formatAuthRejection(error51.reason, env));
@@ -35133,9 +35078,6 @@ function buildTokenRevokeCommand(deps) {
35133
35078
  var authConfigSchema2 = external_exports.object({
35134
35079
  issuer: external_exports.string().min(1),
35135
35080
  clientId: external_exports.string().min(1),
35136
- // `cliClientId` is allowed to be absent so we can distinguish "server
35137
- // too old" from generic malformed-response. The validator below picks
35138
- // it up explicitly.
35139
35081
  cliClientId: external_exports.string().min(1).optional()
35140
35082
  });
35141
35083
  function errorMessage(e2) {
@@ -36056,8 +35998,6 @@ var hostEntrySchema = external_exports.object({
36056
35998
  cli_client_id: external_exports.string().min(1),
36057
35999
  access_token: external_exports.string().min(1),
36058
36000
  refresh_token: external_exports.string().min(1),
36059
- // smol-toml parses unquoted `YYYY-MM-DDTHH:MM:SSZ` as Date and quoted as
36060
- // string. Accept both so a hand-edited file with either shape round-trips.
36061
36001
  expires_at: external_exports.union([external_exports.string().min(1), external_exports.date()])
36062
36002
  });
36063
36003
  var fileSchema = external_exports.object({
@@ -36096,7 +36036,6 @@ function fromHostAuth(value) {
36096
36036
  cli_client_id: value.cliClientId,
36097
36037
  access_token: value.accessToken,
36098
36038
  refresh_token: value.refreshToken,
36099
- // Always emit a quoted ISO 8601 string for unambiguous round-tripping.
36100
36039
  expires_at: value.expiresAt.toISOString()
36101
36040
  };
36102
36041
  }
@@ -37665,11 +37604,7 @@ function renderHuman(channels) {
37665
37604
  return channels.length === 0 ? "No channels connected.\n" : renderTable([
37666
37605
  ["TYPE", "IDENTIFIER", "AMBIENT"],
37667
37606
  ...channels.map(
37668
- (c2) => (
37669
- // Telegram has no readable identifier — the bot token is write-only.
37670
- // Ambient is Slack-only.
37671
- c2.type === "slack" /* Slack */ ? ["slack", c2.slackChannelId, c2.ambient ? "on" : "off"] : ["telegram", "\u2014", "\u2014"]
37672
- )
37607
+ (c2) => c2.type === "slack" /* Slack */ ? ["slack", c2.slackChannelId, c2.ambient ? "on" : "off"] : ["telegram", "\u2014", "\u2014"]
37673
37608
  )
37674
37609
  ]);
37675
37610
  }
@@ -37769,7 +37704,7 @@ function buildSlackConnectCommand(deps) {
37769
37704
  if (!res.ok) {
37770
37705
  if (res.error.kind === "channel-conflict") {
37771
37706
  process.stderr.write(
37772
- "error: Slack channel already bound to another agent\n"
37707
+ "error: this agent is already connected to that Slack channel\n"
37773
37708
  );
37774
37709
  process.exit(EXIT_INVALID_INPUT);
37775
37710
  }
@@ -37802,7 +37737,7 @@ function buildSlackConnectCommand(deps) {
37802
37737
  );
37803
37738
  if (opts.ambient) {
37804
37739
  process.stderr.write(
37805
- "note: the agent reads along in this channel and may chime in without being mentioned; the channel gets a visible notice\n"
37740
+ "note: the agent reads along in this channel and may chime in without being mentioned; ambient is per agent, so others connected here are unaffected\n"
37806
37741
  );
37807
37742
  }
37808
37743
  process.stderr.write(
@@ -39871,11 +39806,6 @@ async function withConnection(url2, fn) {
39871
39806
  };
39872
39807
  const connection2 = new ClientSideConnection(
39873
39808
  () => ({
39874
- // Never answer a permission request. `list` can't trigger one; a
39875
- // `setMode` resume might make the runtime replay a pending request, but
39876
- // auto-approving (or declining) it from this throwaway connection would
39877
- // be wrong — leave it unanswered so a real client (the UI) handles it on
39878
- // its next connection. The connection closes right after the RPC anyway.
39879
39809
  requestPermission() {
39880
39810
  return new Promise(() => {
39881
39811
  });
@@ -40480,7 +40410,7 @@ function createProcessEnvReader() {
40480
40410
 
40481
40411
  // src/modules/cli/infrastructure/package-version.ts
40482
40412
  function readPackageVersion() {
40483
- return true ? "0.2.13" : DEV_VERSION;
40413
+ return true ? "0.2.15-rc1" : DEV_VERSION;
40484
40414
  }
40485
40415
 
40486
40416
  // src/modules/cli/infrastructure/version-probe.ts
@@ -40754,7 +40684,7 @@ function buildConnectCommand(deps) {
40754
40684
  String(DEFAULT_TIMEOUT_SECONDS3)
40755
40685
  ).addHelpText(
40756
40686
  "after",
40757
- '\nExamples:\n dam connection connect github\n dam connection connect github --client-id Iv1.\u2026 --client-secret \u2026 # use your own OAuth app\n dam connection connect github --no-browser\n dam connection connect my-api --header-name X-API-Key --value sk-\u2026\n dam connection connect custom-client-credentials --host api.example.com \\\n --issuer-url https://auth.example.com/realms/main --client-id \u2026 --client-secret \u2026\n dam connection connect github-app --app-id 123456 --installation-id 987654 \\\n --private-key "$(cat app.pem)"\n dam connection connect github-enterprise-app --host ghe.acme.com \\\n --app-id 123456 --installation-id 987654 --private-key "$(cat app.pem)"\n dam connection connect bob --value sk-\u2026 --config model=premium-shell --config chatMode=code\n dam connection connect https://mcp.example.com\n dam connection connect https://mcp.example.com --auth none\n'
40687
+ '\nExamples:\n dam connection connect github\n dam connection connect github --client-id Iv1.\u2026 --client-secret \u2026 # use your own OAuth app\n dam connection connect github --no-browser\n dam connection connect my-api --header-name X-API-Key --value sk-\u2026\n dam connection connect custom-client-credentials --host api.example.com \\\n --issuer-url https://auth.example.com/realms/main --client-id \u2026 --client-secret \u2026\n dam connection connect github-app --app-id 123456 --installation-id 987654 \\\n --private-key "$(cat app.pem)"\n dam connection connect github-enterprise-app --host ghe.acme.com \\\n --app-id 123456 --installation-id 987654 --private-key "$(cat app.pem)"\n dam connection connect bob --value sk-\u2026 --config model=premium-shell --config chatMode=agent\n dam connection connect https://mcp.example.com\n dam connection connect https://mcp.example.com --auth none\n'
40758
40688
  ).action(async (providerOrUrl, opts) => {
40759
40689
  const json2 = opts.json ?? false;
40760
40690
  const timeoutSeconds = parseTimeout2(opts.timeout);
@@ -41746,8 +41676,6 @@ var SECRET_LABELS = {
41746
41676
  header: "New credential value",
41747
41677
  "client-credentials": "New client secret",
41748
41678
  "github-app": "New private key (PEM)",
41749
- // Its own client secret, not its tokens — those come from `reauth`. Only
41750
- // connections carrying their own qualify; the server rejects the rest.
41751
41679
  oauth: "New OAuth client secret"
41752
41680
  };
41753
41681
  function buildUpdateCommand(deps) {
@@ -41975,6 +41903,17 @@ function buildApplyPresetCommand(deps) {
41975
41903
  );
41976
41904
  }
41977
41905
 
41906
+ // src/modules/egress/domain/restart-notice.ts
41907
+ function gatewayRestartNotice(impact) {
41908
+ const clauses = [
41909
+ impact.promoted.length > 0 && `start inspecting requests to ${impact.promoted.join(", ")}`,
41910
+ impact.demoted.length > 0 && `stop inspecting requests to ${impact.demoted.join(", ")}`
41911
+ ].filter((c2) => c2 !== false);
41912
+ return `The network gateway will restart (~5\u201315s) to ${clauses.join(" and ")}.
41913
+ The sandbox keeps running \u2014 its outbound requests are briefly interrupted.
41914
+ `;
41915
+ }
41916
+
41978
41917
  // src/modules/egress/commands/create.ts
41979
41918
  function buildCreateCommand2(deps) {
41980
41919
  return new Command("create").description("Add a network access rule to an Agent").argument("<agent>", "Agent Ref \u2014 name or 'agent-\u2026' ID").requiredOption("--host <h>", "host the rule applies to").option("--method <m>", "HTTP method; default '*'", "*").option("--path <p>", "path pattern; default '*'", "*").addOption(
@@ -41982,7 +41921,7 @@ function buildCreateCommand2(deps) {
41982
41921
  ).option(
41983
41922
  "--server <url>",
41984
41923
  "override the configured server URL for this call"
41985
- ).option("-y, --yes", "skip the path-level restart confirmation").option("--json", "emit the created rule as JSON").addHelpText(
41924
+ ).option("-y, --yes", "skip the gateway restart confirmation").option("--json", "emit the created rule as JSON").addHelpText(
41986
41925
  "after",
41987
41926
  "\nExamples:\n dam network create my-agent --host api.example.com\n dam network create my-agent --host api.example.com --method GET --path /v1/* --yes\n"
41988
41927
  ).action(
@@ -42002,20 +41941,36 @@ function buildCreateCommand2(deps) {
42002
41941
  printResolveError(resolved.error, host);
42003
41942
  process.exit(exitCodeForResolveError(resolved.error));
42004
41943
  }
42005
- const requiresRestart = opts.method !== "*" || opts.path !== "*";
42006
- if (requiresRestart && !opts.yes) {
42007
- if (!process.stdin.isTTY) {
42008
- process.stderr.write(
42009
- "error: path-level rules require --yes on non-interactive stdin\n"
42010
- );
42011
- process.exit(EXIT_INVALID_INPUT);
41944
+ const egress = deps.createEgressService(host);
41945
+ if (!opts.yes) {
41946
+ const existing = await egress.listForAgent(resolved.value.id);
41947
+ if (!existing.ok) {
41948
+ printServiceError(existing.error, host);
41949
+ process.exit(EXIT_RUNTIME_FAILURE);
41950
+ }
41951
+ const impact = gatewayRestartImpact({
41952
+ current: existing.value,
41953
+ adds: [
41954
+ {
41955
+ host: opts.host,
41956
+ method: opts.method,
41957
+ pathPattern: opts.path,
41958
+ source: "manual"
41959
+ }
41960
+ ]
41961
+ });
41962
+ if (impact.willRestart) {
41963
+ if (!process.stdin.isTTY) {
41964
+ process.stderr.write(
41965
+ "error: this rule restarts the network gateway; pass --yes on non-interactive stdin\n"
41966
+ );
41967
+ process.exit(EXIT_INVALID_INPUT);
41968
+ }
41969
+ process.stderr.write(gatewayRestartNotice(impact));
41970
+ if (!await confirm("Continue?")) exitCancelled(opts);
42012
41971
  }
42013
- process.stderr.write(
42014
- "This rule requires path-level enforcement (non-wildcard method/path) and will restart the agent (~5\u201315s).\n"
42015
- );
42016
- if (!await confirm("Continue?")) exitCancelled(opts);
42017
41972
  }
42018
- const result = await deps.createEgressService(host).create({
41973
+ const result = await egress.create({
42019
41974
  agentId: resolved.value.id,
42020
41975
  host: opts.host,
42021
41976
  method: opts.method,
@@ -42154,31 +42109,72 @@ function buildRevokeCommand2(deps) {
42154
42109
  ).argument("<rule-id>", "Rule UUID (copy from `dam network list`)").option(
42155
42110
  "--server <url>",
42156
42111
  "override the configured server URL for this call"
42157
- ).option("--json", "emit { ok, id } as JSON").addHelpText(
42112
+ ).option("-y, --yes", "skip the gateway restart confirmation").option("--json", "emit { ok, id } as JSON").addHelpText(
42158
42113
  "after",
42159
42114
  "\nExamples:\n dam network revoke 3f2a8c0e-2b91-4d6a-9c1b-7e8a1f0a2b3c\n"
42160
- ).action(async (id, opts) => {
42161
- const host = await resolveActiveHost(deps, {
42162
- flag: opts.server ? { server: opts.server } : void 0,
42163
- exitCodes: {
42164
- runtimeFailure: EXIT_RUNTIME_FAILURE,
42165
- belowFloor: EXIT_BELOW_FLOOR
42115
+ ).action(
42116
+ async (id, opts) => {
42117
+ const host = await resolveActiveHost(deps, {
42118
+ flag: opts.server ? { server: opts.server } : void 0,
42119
+ exitCodes: {
42120
+ runtimeFailure: EXIT_RUNTIME_FAILURE,
42121
+ belowFloor: EXIT_BELOW_FLOOR
42122
+ }
42123
+ });
42124
+ const egress = deps.createEgressService(host);
42125
+ const current = await egress.get(id);
42126
+ if (!current.ok) {
42127
+ const failure = current.error;
42128
+ if (failure.kind === "rule-lookup-unsupported") {
42129
+ if (!opts.yes) {
42130
+ process.stderr.write(
42131
+ "error: this server is too old to report whether revoking restarts the network gateway; re-run with --yes to revoke anyway\n"
42132
+ );
42133
+ process.exit(EXIT_INVALID_INPUT);
42134
+ }
42135
+ } else if (failure.kind !== "rule-not-found") {
42136
+ printServiceError(failure, host);
42137
+ process.exit(EXIT_RUNTIME_FAILURE);
42138
+ }
42166
42139
  }
42167
- });
42168
- const result = await deps.createEgressService(host).revoke(id);
42169
- if (!result.ok) {
42170
- printServiceError(result.error, host);
42171
- process.exit(EXIT_RUNTIME_FAILURE);
42172
- }
42173
- if (opts.json) {
42174
- process.stdout.write(`${JSON.stringify({ ok: true, id })}
42140
+ if (current.ok && !opts.yes) {
42141
+ const siblings = await egress.listForAgent(current.value.agentId);
42142
+ if (!siblings.ok) {
42143
+ process.stderr.write(
42144
+ "error: could not read the sandbox's rules to tell whether revoking restarts the network gateway; re-run with --yes to revoke anyway\n"
42145
+ );
42146
+ process.exit(EXIT_INVALID_INPUT);
42147
+ }
42148
+ const impact = gatewayRestartImpact({
42149
+ current: siblings.value,
42150
+ removeIds: [id]
42151
+ });
42152
+ if (impact.willRestart) {
42153
+ if (!process.stdin.isTTY) {
42154
+ process.stderr.write(
42155
+ "error: this revoke restarts the network gateway; pass --yes on non-interactive stdin\n"
42156
+ );
42157
+ process.exit(EXIT_INVALID_INPUT);
42158
+ }
42159
+ process.stderr.write(gatewayRestartNotice(impact));
42160
+ if (!await confirm("Continue?")) exitCancelled(opts);
42161
+ }
42162
+ }
42163
+ const result = await egress.revoke(id);
42164
+ if (!result.ok) {
42165
+ printServiceError(result.error, host);
42166
+ process.exit(EXIT_RUNTIME_FAILURE);
42167
+ }
42168
+ if (opts.json) {
42169
+ process.stdout.write(`${JSON.stringify({ ok: true, id })}
42175
42170
  `);
42176
- } else {
42177
- process.stdout.write(`\u2713 Revoked rule ${id}.
42171
+ } else {
42172
+ process.stdout.write(`\u2713 Revoked rule ${id}.
42178
42173
  `);
42174
+ }
42175
+ process.exit(EXIT_SUCCESS);
42179
42176
  }
42180
- process.exit(EXIT_SUCCESS);
42181
- });
42177
+ );
42182
42178
  }
42183
42179
 
42184
42180
  // src/modules/egress/commands/trusted-hosts.ts
@@ -42218,7 +42214,7 @@ function buildUpdateCommand2(deps) {
42218
42214
  ).option(
42219
42215
  "--server <url>",
42220
42216
  "override the configured server URL for this call"
42221
- ).option("-y, --yes", "skip the path-level restart confirmation").option("--json", "emit the updated rule as JSON").addHelpText(
42217
+ ).option("-y, --yes", "skip the gateway restart confirmation").option("--json", "emit the updated rule as JSON").addHelpText(
42222
42218
  "after",
42223
42219
  "\nExamples:\n dam network update 3f2a8c0e-... --verdict deny\n dam network update 3f2a8c0e-... --method GET --path /v1/* --yes\n"
42224
42220
  ).action(
@@ -42236,20 +42232,60 @@ function buildUpdateCommand2(deps) {
42236
42232
  belowFloor: EXIT_BELOW_FLOOR
42237
42233
  }
42238
42234
  });
42239
- const requiresRestart = opts.method !== void 0 && opts.method !== "*" || opts.path !== void 0 && opts.path !== "*";
42240
- if (requiresRestart && !opts.yes) {
42241
- if (!process.stdin.isTTY) {
42235
+ const egress = deps.createEgressService(host);
42236
+ const current = await egress.get(id);
42237
+ if (!current.ok) {
42238
+ const failure = current.error;
42239
+ if (failure.kind === "rule-not-found") {
42242
42240
  process.stderr.write(
42243
- "error: path-level rules require --yes on non-interactive stdin\n"
42241
+ `error: network access rule not found: ${failure.id}
42242
+ `
42244
42243
  );
42245
- process.exit(EXIT_INVALID_INPUT);
42244
+ process.exit(EXIT_RULE_NOT_FOUND);
42245
+ } else if (failure.kind === "rule-lookup-unsupported") {
42246
+ if (!opts.yes) {
42247
+ process.stderr.write(
42248
+ "error: this server is too old to report whether this change restarts the network gateway; re-run with --yes to apply it anyway\n"
42249
+ );
42250
+ process.exit(EXIT_INVALID_INPUT);
42251
+ }
42252
+ } else {
42253
+ printServiceError(failure, host);
42254
+ process.exit(EXIT_RUNTIME_FAILURE);
42255
+ }
42256
+ }
42257
+ if (current.ok) {
42258
+ const rule = current.value;
42259
+ const siblings = await egress.listForAgent(rule.agentId);
42260
+ if (!siblings.ok) {
42261
+ printServiceError(siblings.error, host);
42262
+ process.exit(EXIT_RUNTIME_FAILURE);
42263
+ }
42264
+ const impact = gatewayRestartImpact({
42265
+ current: siblings.value,
42266
+ removeIds: [id],
42267
+ adds: [
42268
+ {
42269
+ host: rule.host,
42270
+ ...rule.port ? { port: rule.port } : {},
42271
+ method: opts.method ?? rule.method,
42272
+ pathPattern: opts.path ?? rule.pathPattern,
42273
+ source: "manual"
42274
+ }
42275
+ ]
42276
+ });
42277
+ if (impact.willRestart && !opts.yes) {
42278
+ if (!process.stdin.isTTY) {
42279
+ process.stderr.write(
42280
+ "error: this change restarts the network gateway; pass --yes on non-interactive stdin\n"
42281
+ );
42282
+ process.exit(EXIT_INVALID_INPUT);
42283
+ }
42284
+ process.stderr.write(gatewayRestartNotice(impact));
42285
+ if (!await confirm("Continue?")) exitCancelled(opts);
42246
42286
  }
42247
- process.stderr.write(
42248
- "This rule requires path-level enforcement (non-wildcard method/path) and will restart the agent (~5\u201315s).\n"
42249
- );
42250
- if (!await confirm("Continue?")) exitCancelled(opts);
42251
42287
  }
42252
- const result = await deps.createEgressService(host).update({
42288
+ const result = await egress.update({
42253
42289
  id,
42254
42290
  method: opts.method,
42255
42291
  pathPattern: opts.path,
@@ -42288,6 +42324,18 @@ function createEgressService(deps) {
42288
42324
  () => deps.trpc.egressRules.listForAgent.query({ agentId })
42289
42325
  );
42290
42326
  },
42327
+ async get(id) {
42328
+ try {
42329
+ const view = await deps.trpc.egressRules.get.query({ id });
42330
+ return ok2(view);
42331
+ } catch (e2) {
42332
+ if (e2?.data?.code === "NOT_FOUND") {
42333
+ const reason = e2 instanceof Error ? e2.message : String(e2);
42334
+ return /egress rule not found/i.test(reason) ? err2({ kind: "rule-not-found", id }) : err2({ kind: "rule-lookup-unsupported", reason });
42335
+ }
42336
+ return classifyTrpcError(e2);
42337
+ }
42338
+ },
42291
42339
  async currentPreset(agentId) {
42292
42340
  return trpcCall(
42293
42341
  () => deps.trpc.egressRules.currentPreset.query({ agentId })
@@ -42459,8 +42507,9 @@ function printTrpcReadError(e2, path2, host) {
42459
42507
  return;
42460
42508
  }
42461
42509
  if (code === "PAYLOAD_TOO_LARGE") {
42510
+ const detail = serverDetail(e2);
42462
42511
  process.stderr.write(
42463
- `error: ${path2} exceeds the 10 MB cap for tRPC-based reads. Streaming transfer for individual large files isn't implemented yet (use \`dam import\` for bulk transfer).
42512
+ `error: ${path2} exceeds the server's per-file cap` + (detail ? ` (${detail})` : "") + `. Streaming transfer for individual large files isn't implemented yet.
42464
42513
  `
42465
42514
  );
42466
42515
  return;
@@ -42612,9 +42661,7 @@ function buildFilePutCommand(deps) {
42612
42661
  );
42613
42662
  }
42614
42663
  function printTrpcUploadError(e2, remotePath, host) {
42615
- const trpcErr = e2 instanceof TRPCClientError ? e2 : void 0;
42616
- const code = trpcErr?.data?.code;
42617
- const message = trpcErr?.data?.message ?? "";
42664
+ const code = e2 instanceof TRPCClientError ? e2.data?.code : void 0;
42618
42665
  if (code === "CONFLICT") {
42619
42666
  process.stderr.write(
42620
42667
  `error: ${remotePath} already exists on the agent; pass --overwrite to clobber
@@ -42623,13 +42670,14 @@ function printTrpcUploadError(e2, remotePath, host) {
42623
42670
  return;
42624
42671
  }
42625
42672
  if (code === "FORBIDDEN") {
42626
- process.stderr.write(`error: forbidden path: ${message || remotePath}
42673
+ process.stderr.write(`error: forbidden path: ${remotePath}
42627
42674
  `);
42628
42675
  return;
42629
42676
  }
42630
42677
  if (code === "PAYLOAD_TOO_LARGE") {
42678
+ const detail = serverDetail(e2);
42631
42679
  process.stderr.write(
42632
- `error: ${remotePath} exceeds the server's per-file cap` + (message ? ` (${message})` : "") + `. Streaming transfer for individual large files isn't implemented yet (use \`dam import\` for bulk transfer).
42680
+ `error: ${remotePath} exceeds the server's per-file cap` + (detail ? ` (${detail})` : "") + `. Streaming transfer for individual large files isn't implemented yet (use \`dam import\` for bulk transfer).
42633
42681
  `
42634
42682
  );
42635
42683
  return;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dam-agents/cli",
3
3
  "author": "IBM Corp.",
4
- "version": "0.2.13",
4
+ "version": "0.2.15-rc1",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "homepage": "https://github.com/dam-agents/dam/tree/main/packages/cli#readme",