@dam-agents/cli 0.2.7 → 0.2.9-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.
- package/dist/bin.js +602 -172
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -26799,6 +26799,18 @@ var skillListInputSchema = external_exports.object({
|
|
|
26799
26799
|
sourceId: external_exports.string().min(1),
|
|
26800
26800
|
agentId: external_exports.string().min(1).optional()
|
|
26801
26801
|
});
|
|
26802
|
+
var skillGetContentInputSchema = external_exports.object({
|
|
26803
|
+
sourceId: external_exports.string().min(1),
|
|
26804
|
+
name: external_exports.string().min(1),
|
|
26805
|
+
agentId: external_exports.string().min(1).optional()
|
|
26806
|
+
});
|
|
26807
|
+
var skillContentSchema = external_exports.object({
|
|
26808
|
+
content: external_exports.string(),
|
|
26809
|
+
/** Source-relative directory the SKILL.md was found in, when resolvable —
|
|
26810
|
+
* lets the UI build an accurate blob link instead of guessing the dir from
|
|
26811
|
+
* the (frontmatter) skill name. */
|
|
26812
|
+
dir: external_exports.string().optional()
|
|
26813
|
+
});
|
|
26802
26814
|
var skillInstallInputSchema = external_exports.object({
|
|
26803
26815
|
agentId: external_exports.string().min(1),
|
|
26804
26816
|
source: external_exports.string().url(),
|
|
@@ -26892,6 +26904,38 @@ var repoSchema = external_exports.object({
|
|
|
26892
26904
|
compatibleTemplates: external_exports.array(external_exports.string()).default([])
|
|
26893
26905
|
});
|
|
26894
26906
|
|
|
26907
|
+
// ../api-server-api/src/modules/invocations/schemas.ts
|
|
26908
|
+
var DEFAULT_INVOCATION_TTL_MS = 60 * 60 * 1e3;
|
|
26909
|
+
var MIN_INVOCATION_TTL_MS = 60 * 1e3;
|
|
26910
|
+
var MAX_INVOCATION_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
26911
|
+
var spawnInvocationRequestSchema = external_exports.object({
|
|
26912
|
+
image: external_exports.string().min(1).optional(),
|
|
26913
|
+
templateId: external_exports.string().min(1).optional(),
|
|
26914
|
+
connections: external_exports.array(external_exports.string().min(1)).optional(),
|
|
26915
|
+
prompt: external_exports.string().min(1),
|
|
26916
|
+
// The result JSON Schema — arbitrary JSON, validated structurally by ajv
|
|
26917
|
+
// when the target reports (a malformed schema is rejected at spawn).
|
|
26918
|
+
schema: external_exports.unknown(),
|
|
26919
|
+
// Optional liveness deadline for this target, in ms. Bounded server-side; a
|
|
26920
|
+
// shorter value fails a wedged/misconfigured target fast, a longer one lets
|
|
26921
|
+
// a heavy target run past the default hour.
|
|
26922
|
+
ttlMs: external_exports.number().int().min(MIN_INVOCATION_TTL_MS).max(MAX_INVOCATION_TTL_MS).optional(),
|
|
26923
|
+
// Optional resource limits. A heavy Make (clone + install + build)
|
|
26924
|
+
// OOM-kills at the template's small default memory, so let the driver raise
|
|
26925
|
+
// it. Same grammar and floors as the agent size knob.
|
|
26926
|
+
memory: external_exports.string().regex(/^\d+(Mi|Gi)$/, "memory must look like '512Mi' or '4Gi'").optional(),
|
|
26927
|
+
cpu: external_exports.string().regex(/^\d+(\.\d+)?m?$/, "cpu must look like '2', '0.5' or '500m'").optional()
|
|
26928
|
+
}).refine((d2) => d2.image !== void 0 || d2.templateId !== void 0, {
|
|
26929
|
+
message: "either image or templateId is required"
|
|
26930
|
+
});
|
|
26931
|
+
var spawnInvocationResponseSchema = external_exports.object({
|
|
26932
|
+
id: external_exports.string().min(1)
|
|
26933
|
+
});
|
|
26934
|
+
var invocationViewSchema = external_exports.object({
|
|
26935
|
+
status: external_exports.enum(["running", "done", "failed"]),
|
|
26936
|
+
result: external_exports.unknown()
|
|
26937
|
+
});
|
|
26938
|
+
|
|
26895
26939
|
// ../agent-runtime-api/src/modules/files/schemas.ts
|
|
26896
26940
|
var pathSchema = external_exports.string().min(1);
|
|
26897
26941
|
var fileListDirsInputSchema = external_exports.object({
|
|
@@ -27209,6 +27253,10 @@ var harnessConfigSettledSchema = external_exports.object({
|
|
|
27209
27253
|
|
|
27210
27254
|
// ../api-server-api/src/modules/egress-rules/schemas.ts
|
|
27211
27255
|
var ruleVerdictSchema = external_exports.enum(["allow", "deny"]);
|
|
27256
|
+
var HOSTNAME = /^(\*\.)?[a-zA-Z0-9]([-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?)*$/;
|
|
27257
|
+
var egressHostSchema = external_exports.string().min(1).max(253).refine((h2) => h2 === "*" || HOSTNAME.test(h2), {
|
|
27258
|
+
message: "host must be a DNS hostname, a *.wildcard, or bare *"
|
|
27259
|
+
});
|
|
27212
27260
|
var egressPresetSchema = external_exports.enum(["none", "trusted", "all"]);
|
|
27213
27261
|
var egressRuleListForAgentInputSchema = external_exports.object({
|
|
27214
27262
|
agentId: external_exports.string().min(1)
|
|
@@ -27218,7 +27266,7 @@ var egressRuleCurrentPresetInputSchema = external_exports.object({
|
|
|
27218
27266
|
});
|
|
27219
27267
|
var egressRuleCreateInputSchema = external_exports.object({
|
|
27220
27268
|
agentId: external_exports.string().min(1),
|
|
27221
|
-
host:
|
|
27269
|
+
host: egressHostSchema,
|
|
27222
27270
|
// Upstream port; omit for 443. Promotes the host onto the L7 chain.
|
|
27223
27271
|
port: external_exports.number().int().min(1).max(65535).optional(),
|
|
27224
27272
|
method: external_exports.string().min(1).default("*"),
|
|
@@ -27257,6 +27305,9 @@ var agentSizeSchema = external_exports.object({
|
|
|
27257
27305
|
cpu: cpuQuantitySchema.optional(),
|
|
27258
27306
|
memory: memoryQuantitySchema.optional()
|
|
27259
27307
|
});
|
|
27308
|
+
var agentUpgradeInputSchema = idSchema.extend({
|
|
27309
|
+
expectedToImage: external_exports.string().min(1).optional()
|
|
27310
|
+
});
|
|
27260
27311
|
var agentCreateInputSchema = external_exports.object({
|
|
27261
27312
|
name: external_exports.string().min(1).refine((n) => !n.startsWith("agent-"), {
|
|
27262
27313
|
message: "agent name cannot start with 'agent-' (reserved for IDs)"
|
|
@@ -27290,7 +27341,15 @@ var agentCreateInputSchema = external_exports.object({
|
|
|
27290
27341
|
// dimensions inherit the template's limits, else the chart default.
|
|
27291
27342
|
// Requests are derived server-side — never a user concept. Floors match
|
|
27292
27343
|
// the chart's derivation floors; the budget gate is the only ceiling.
|
|
27293
|
-
size: agentSizeSchema.optional()
|
|
27344
|
+
size: agentSizeSchema.optional(),
|
|
27345
|
+
// Sweepable (#2816): mark this agent for automatic deletion by the Agent
|
|
27346
|
+
// Sweep once it hibernates. Set on ephemeral agents (Invocation targets);
|
|
27347
|
+
// durable owned agents omit it. Stamped as an annotation at create.
|
|
27348
|
+
sweepable: external_exports.boolean().optional(),
|
|
27349
|
+
// Agent Lifetime (#2816): optional grace in ms a Sweepable agent may stay
|
|
27350
|
+
// hibernated before the Sweep deletes it. Default zero — deleted as soon
|
|
27351
|
+
// as it hibernates. Ignored unless `sweepable`.
|
|
27352
|
+
lifetimeMs: external_exports.number().int().min(0).optional()
|
|
27294
27353
|
}).refine((d2) => d2.templateId !== void 0 || d2.image !== void 0, {
|
|
27295
27354
|
message: "Either templateId or image is required"
|
|
27296
27355
|
});
|
|
@@ -27310,11 +27369,32 @@ var agentUpdateInputSchema = external_exports.object({
|
|
|
27310
27369
|
});
|
|
27311
27370
|
var agentConnectSlackInputSchema = external_exports.object({
|
|
27312
27371
|
id: external_exports.string().min(1),
|
|
27313
|
-
slackChannelId: external_exports.string().min(1)
|
|
27372
|
+
slackChannelId: external_exports.string().min(1),
|
|
27373
|
+
// Access mode; absent = person-scoped.
|
|
27374
|
+
mode: external_exports.enum(["shared", "person-scoped"]).optional(),
|
|
27375
|
+
// Ambient mode; absent = off. Unlike mode it is mutable: re-connecting
|
|
27376
|
+
// with the same mode updates it in place.
|
|
27377
|
+
ambient: external_exports.boolean().optional()
|
|
27378
|
+
}).refine((v2) => !v2.ambient || v2.mode === "shared", {
|
|
27379
|
+
message: "Ambient mode requires a shared binding",
|
|
27380
|
+
path: ["ambient"]
|
|
27381
|
+
});
|
|
27382
|
+
var agentListTelegramChatsInputSchema = external_exports.object({
|
|
27383
|
+
agentId: external_exports.string().min(1)
|
|
27314
27384
|
});
|
|
27315
|
-
var
|
|
27316
|
-
|
|
27317
|
-
|
|
27385
|
+
var agentUnbindTelegramChatInputSchema = external_exports.object({
|
|
27386
|
+
agentId: external_exports.string().min(1),
|
|
27387
|
+
conversationId: external_exports.string().min(1)
|
|
27388
|
+
});
|
|
27389
|
+
var agentBindTelegramChatInputSchema = external_exports.object({
|
|
27390
|
+
agentId: external_exports.string().min(1),
|
|
27391
|
+
// Opaque bind-flow id minted by the Telegram OAuth callback.
|
|
27392
|
+
flowId: external_exports.string().min(1)
|
|
27393
|
+
});
|
|
27394
|
+
var agentBindSlackChannelInputSchema = external_exports.object({
|
|
27395
|
+
agentId: external_exports.string().min(1),
|
|
27396
|
+
// Opaque bind-flow id minted by the Slack in-chat bind OAuth callback.
|
|
27397
|
+
flowId: external_exports.string().min(1)
|
|
27318
27398
|
});
|
|
27319
27399
|
|
|
27320
27400
|
// ../api-server-api/src/modules/schedules/schemas.ts
|
|
@@ -27417,6 +27497,83 @@ var experimentAddArmInputSchema = external_exports.object({
|
|
|
27417
27497
|
armVariation: armVariationSchema.default("")
|
|
27418
27498
|
});
|
|
27419
27499
|
|
|
27500
|
+
// ../api-server-api/src/modules/artifact-library/schemas.ts
|
|
27501
|
+
var artifactKindSchema = external_exports.enum([
|
|
27502
|
+
"html",
|
|
27503
|
+
"jsx",
|
|
27504
|
+
"markdown",
|
|
27505
|
+
"code",
|
|
27506
|
+
"text",
|
|
27507
|
+
"binary"
|
|
27508
|
+
]);
|
|
27509
|
+
var artifactVisibilitySchema = external_exports.enum(["private", "public"]);
|
|
27510
|
+
var titleSchema = external_exports.string().trim().min(1, "title is required").max(300);
|
|
27511
|
+
var fileNameSchema = external_exports.string().trim().min(1).max(255);
|
|
27512
|
+
var expiresInHoursSchema = external_exports.number().int().positive().max(24 * 365 * 10);
|
|
27513
|
+
var artifactIdInputSchema = external_exports.object({ id: external_exports.string().min(1) });
|
|
27514
|
+
var artifactListInputSchema = external_exports.object({
|
|
27515
|
+
folderId: external_exports.string().min(1).nullish(),
|
|
27516
|
+
agentId: external_exports.string().min(1).optional(),
|
|
27517
|
+
search: external_exports.string().trim().max(200).optional()
|
|
27518
|
+
});
|
|
27519
|
+
var artifactContentInputSchema = external_exports.object({
|
|
27520
|
+
id: external_exports.string().min(1),
|
|
27521
|
+
version: external_exports.number().int().positive().optional()
|
|
27522
|
+
});
|
|
27523
|
+
var INLINE_CONTENT_MAX_BYTES = 2 * 1024 * 1024;
|
|
27524
|
+
var contentOrUploadRef = {
|
|
27525
|
+
content: external_exports.string().max(INLINE_CONTENT_MAX_BYTES).optional(),
|
|
27526
|
+
uploadRef: external_exports.string().min(1).max(1024).optional()
|
|
27527
|
+
};
|
|
27528
|
+
var artifactCreateInputSchema = external_exports.object({
|
|
27529
|
+
title: titleSchema,
|
|
27530
|
+
...contentOrUploadRef,
|
|
27531
|
+
fileName: fileNameSchema.optional(),
|
|
27532
|
+
kind: artifactKindSchema.optional(),
|
|
27533
|
+
contentType: external_exports.string().trim().min(1).max(200).optional(),
|
|
27534
|
+
folderId: external_exports.string().min(1).optional(),
|
|
27535
|
+
visibility: artifactVisibilitySchema.optional(),
|
|
27536
|
+
expiresInHours: expiresInHoursSchema.nullish()
|
|
27537
|
+
}).refine((v2) => v2.content == null !== (v2.uploadRef == null), {
|
|
27538
|
+
message: "provide exactly one of content or uploadRef",
|
|
27539
|
+
path: ["content"]
|
|
27540
|
+
});
|
|
27541
|
+
var artifactUpdateInputSchema = external_exports.object({
|
|
27542
|
+
id: external_exports.string().min(1),
|
|
27543
|
+
title: titleSchema.optional(),
|
|
27544
|
+
folderId: external_exports.string().min(1).nullish(),
|
|
27545
|
+
...contentOrUploadRef,
|
|
27546
|
+
fileName: fileNameSchema.optional(),
|
|
27547
|
+
kind: artifactKindSchema.optional(),
|
|
27548
|
+
contentType: external_exports.string().trim().min(1).max(200).optional()
|
|
27549
|
+
}).refine((v2) => !(v2.content != null && v2.uploadRef != null), {
|
|
27550
|
+
message: "provide at most one of content or uploadRef",
|
|
27551
|
+
path: ["content"]
|
|
27552
|
+
});
|
|
27553
|
+
var artifactSharingInputSchema = external_exports.object({
|
|
27554
|
+
id: external_exports.string().min(1),
|
|
27555
|
+
visibility: artifactVisibilitySchema.optional(),
|
|
27556
|
+
expiresInHours: expiresInHoursSchema.nullish()
|
|
27557
|
+
});
|
|
27558
|
+
var artifactUploadUrlInputSchema = external_exports.object({
|
|
27559
|
+
fileName: fileNameSchema
|
|
27560
|
+
});
|
|
27561
|
+
var folderCreateInputSchema = external_exports.object({
|
|
27562
|
+
name: external_exports.string().trim().min(1, "name is required").max(200)
|
|
27563
|
+
});
|
|
27564
|
+
var folderUpdateInputSchema = external_exports.object({
|
|
27565
|
+
id: external_exports.string().min(1),
|
|
27566
|
+
name: external_exports.string().trim().min(1).max(200).optional()
|
|
27567
|
+
});
|
|
27568
|
+
var folderIdInputSchema = external_exports.object({ id: external_exports.string().min(1) });
|
|
27569
|
+
|
|
27570
|
+
// ../api-server-api/src/modules/features/schemas.ts
|
|
27571
|
+
var featureIdSchema = external_exports.enum(["advanced-connections", "experiments"]);
|
|
27572
|
+
var featureSetFlagInputSchema = external_exports.object({
|
|
27573
|
+
feature: featureIdSchema,
|
|
27574
|
+
enabled: external_exports.boolean()
|
|
27575
|
+
});
|
|
27576
|
+
|
|
27420
27577
|
// ../../node_modules/.pnpm/rrule@2.8.1/node_modules/rrule/dist/esm/index.js
|
|
27421
27578
|
var esm_exports = {};
|
|
27422
27579
|
__export(esm_exports, {
|
|
@@ -30648,6 +30805,17 @@ var clientCredentialsAuth = external_exports.object({
|
|
|
30648
30805
|
tokenEndpointAcceptJson: external_exports.boolean().optional(),
|
|
30649
30806
|
host: external_exports.string().min(1).optional()
|
|
30650
30807
|
});
|
|
30808
|
+
var githubAppAuth = external_exports.object({
|
|
30809
|
+
kind: external_exports.literal("github-app"),
|
|
30810
|
+
appId: external_exports.string().min(1),
|
|
30811
|
+
installationId: external_exports.string().min(1),
|
|
30812
|
+
privateKeyRef: secretRef,
|
|
30813
|
+
accessTokenRef: secretRef,
|
|
30814
|
+
apiBaseUrl: external_exports.string().url(),
|
|
30815
|
+
expiresAt: external_exports.number().int().optional(),
|
|
30816
|
+
connectedAt: external_exports.number().int().optional(),
|
|
30817
|
+
host: external_exports.string().min(1).optional()
|
|
30818
|
+
});
|
|
30651
30819
|
var headerAuth = external_exports.object({
|
|
30652
30820
|
kind: external_exports.literal("header"),
|
|
30653
30821
|
valueRef: secretRef,
|
|
@@ -30660,6 +30828,7 @@ var noneAuth = external_exports.object({
|
|
|
30660
30828
|
var authConfig = external_exports.discriminatedUnion("kind", [
|
|
30661
30829
|
oauthAuth,
|
|
30662
30830
|
clientCredentialsAuth,
|
|
30831
|
+
githubAppAuth,
|
|
30663
30832
|
headerAuth,
|
|
30664
30833
|
noneAuth
|
|
30665
30834
|
]);
|
|
@@ -30681,6 +30850,7 @@ var connectionStatus = external_exports.enum([
|
|
|
30681
30850
|
var authKind = external_exports.enum([
|
|
30682
30851
|
"oauth",
|
|
30683
30852
|
"client-credentials",
|
|
30853
|
+
"github-app",
|
|
30684
30854
|
"header",
|
|
30685
30855
|
"none"
|
|
30686
30856
|
]);
|
|
@@ -30708,6 +30878,8 @@ var templateInput = external_exports.object({
|
|
|
30708
30878
|
state: templateInputState,
|
|
30709
30879
|
presetValue: external_exports.string().optional(),
|
|
30710
30880
|
secret: external_exports.boolean().optional(),
|
|
30881
|
+
// Renders as a multi-line textarea rather than a single-line input (e.g. a PEM private key).
|
|
30882
|
+
multiline: external_exports.boolean().optional(),
|
|
30711
30883
|
// Marks a config input the form packs into `configInputs` rather than the typed auth fields.
|
|
30712
30884
|
configInput: external_exports.boolean().optional(),
|
|
30713
30885
|
label: external_exports.string().optional(),
|
|
@@ -30823,14 +30995,26 @@ var clientCredentialsCreateInput = external_exports.object({
|
|
|
30823
30995
|
"env var name must be letters, digits, and underscores (not starting with a digit)"
|
|
30824
30996
|
).optional()
|
|
30825
30997
|
});
|
|
30998
|
+
var githubAppCreateInput = external_exports.object({
|
|
30999
|
+
...commonFields,
|
|
31000
|
+
authKind: external_exports.literal("github-app"),
|
|
31001
|
+
appId: external_exports.string().min(1),
|
|
31002
|
+
installationId: external_exports.string().min(1),
|
|
31003
|
+
privateKey: external_exports.string().min(1)
|
|
31004
|
+
});
|
|
30826
31005
|
var noneCreateInput = external_exports.object({
|
|
30827
31006
|
...commonFields,
|
|
30828
31007
|
authKind: external_exports.literal("none"),
|
|
30829
|
-
url: external_exports.string().url().optional()
|
|
31008
|
+
url: external_exports.string().url().optional(),
|
|
31009
|
+
// Optional header credential (API key) for MCP servers guarded by a
|
|
31010
|
+
// static header — injected at the gateway, never written to harness config.
|
|
31011
|
+
headerName: external_exports.string().min(1).optional(),
|
|
31012
|
+
value: external_exports.string().min(1).optional()
|
|
30830
31013
|
});
|
|
30831
31014
|
var connectionCreateInputSchema = external_exports.discriminatedUnion("authKind", [
|
|
30832
31015
|
oauthCreateInput,
|
|
30833
31016
|
clientCredentialsCreateInput,
|
|
31017
|
+
githubAppCreateInput,
|
|
30834
31018
|
headerCreateInput,
|
|
30835
31019
|
noneCreateInput
|
|
30836
31020
|
]);
|
|
@@ -30935,7 +31119,7 @@ function describeApprovalPayload(payload) {
|
|
|
30935
31119
|
if (payload.kind === "ext_authz") {
|
|
30936
31120
|
return {
|
|
30937
31121
|
title: `${payload.method} ${payload.host}`,
|
|
30938
|
-
subtitle: payload.path
|
|
31122
|
+
subtitle: payload.viaAgentId ? `${payload.path} \xB7 via ${payload.viaAgentId}` : payload.path
|
|
30939
31123
|
};
|
|
30940
31124
|
}
|
|
30941
31125
|
return { title: payload.toolName ?? "tool call", subtitle: "" };
|
|
@@ -30984,7 +31168,7 @@ var platformTurnEndedNotificationSchema = external_exports.object({
|
|
|
30984
31168
|
var brandSchema = external_exports.object({
|
|
30985
31169
|
name: external_exports.string(),
|
|
30986
31170
|
short: external_exports.string(),
|
|
30987
|
-
|
|
31171
|
+
title: external_exports.string(),
|
|
30988
31172
|
theme: external_exports.object({
|
|
30989
31173
|
light: external_exports.object({
|
|
30990
31174
|
accent: external_exports.string(),
|
|
@@ -31073,12 +31257,24 @@ var e2ePerformFetchInputSchema = external_exports.object({
|
|
|
31073
31257
|
url: external_exports.string().url(),
|
|
31074
31258
|
headers: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
31075
31259
|
}).strict();
|
|
31260
|
+
var e2eSpawnInvocationInputSchema = external_exports.object({
|
|
31261
|
+
agentId: external_exports.string().min(1),
|
|
31262
|
+
prompt: external_exports.string().min(1),
|
|
31263
|
+
schema: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
31264
|
+
templateId: external_exports.string().min(1).optional(),
|
|
31265
|
+
image: external_exports.string().min(1).optional(),
|
|
31266
|
+
connections: external_exports.array(external_exports.string()).optional(),
|
|
31267
|
+
ttlMs: external_exports.number().int().positive().optional()
|
|
31268
|
+
}).strict();
|
|
31269
|
+
var spawnInvocationResultSchema = external_exports.object({ id: external_exports.string().min(1) }).strict();
|
|
31076
31270
|
var slackFireMentionInputSchema = external_exports.object({
|
|
31077
31271
|
user: external_exports.string().min(1),
|
|
31078
31272
|
channel: external_exports.string().min(1),
|
|
31079
31273
|
ts: external_exports.string().min(1),
|
|
31080
31274
|
threadTs: external_exports.string().optional(),
|
|
31081
|
-
text: external_exports.string()
|
|
31275
|
+
text: external_exports.string(),
|
|
31276
|
+
/** Workspace id; present so the fake exercises the live-streaming path. */
|
|
31277
|
+
teamId: external_exports.string().optional()
|
|
31082
31278
|
}).strict();
|
|
31083
31279
|
var slackFireCommandInputSchema = external_exports.object({
|
|
31084
31280
|
text: external_exports.string(),
|
|
@@ -31110,6 +31306,33 @@ var slackOutboundRecordSchema = external_exports.discriminatedUnion("kind", [
|
|
|
31110
31306
|
kind: external_exports.literal("upload"),
|
|
31111
31307
|
channelId: external_exports.string(),
|
|
31112
31308
|
filename: external_exports.string()
|
|
31309
|
+
}).strict(),
|
|
31310
|
+
external_exports.object({
|
|
31311
|
+
kind: external_exports.literal("stream_start"),
|
|
31312
|
+
channel: external_exports.string(),
|
|
31313
|
+
threadTs: external_exports.string(),
|
|
31314
|
+
ts: external_exports.string(),
|
|
31315
|
+
text: external_exports.string(),
|
|
31316
|
+
recipientTeamId: external_exports.string().optional(),
|
|
31317
|
+
recipientUserId: external_exports.string().optional()
|
|
31318
|
+
}).strict(),
|
|
31319
|
+
external_exports.object({
|
|
31320
|
+
kind: external_exports.literal("stream_append"),
|
|
31321
|
+
channel: external_exports.string(),
|
|
31322
|
+
ts: external_exports.string(),
|
|
31323
|
+
text: external_exports.string()
|
|
31324
|
+
}).strict(),
|
|
31325
|
+
external_exports.object({
|
|
31326
|
+
kind: external_exports.literal("stream_stop"),
|
|
31327
|
+
channel: external_exports.string(),
|
|
31328
|
+
ts: external_exports.string(),
|
|
31329
|
+
text: external_exports.string().optional()
|
|
31330
|
+
}).strict(),
|
|
31331
|
+
external_exports.object({
|
|
31332
|
+
kind: external_exports.literal("status"),
|
|
31333
|
+
channel: external_exports.string(),
|
|
31334
|
+
threadTs: external_exports.string(),
|
|
31335
|
+
status: external_exports.string()
|
|
31113
31336
|
}).strict()
|
|
31114
31337
|
]);
|
|
31115
31338
|
var slackReadOutboundResultSchema = external_exports.object({ records: external_exports.array(slackOutboundRecordSchema) }).strict();
|
|
@@ -31436,6 +31659,7 @@ var EXIT_RULE_NOT_FOUND = 6;
|
|
|
31436
31659
|
var EXIT_AGENT_NOT_REACHABLE = 7;
|
|
31437
31660
|
var EXIT_APPROVAL_NOT_ACTIONABLE = 8;
|
|
31438
31661
|
var EXIT_SCHEDULE_NOT_FOUND = 9;
|
|
31662
|
+
var EXIT_TERMS_NOT_ACCEPTED = 10;
|
|
31439
31663
|
var EXIT_SIGINT = 130;
|
|
31440
31664
|
|
|
31441
31665
|
// src/modules/agent/commands/create.ts
|
|
@@ -37247,11 +37471,16 @@ function buildDisallowCommand(deps) {
|
|
|
37247
37471
|
// src/modules/channel/commands/list.ts
|
|
37248
37472
|
function renderHuman(channels, allowedUserEmails) {
|
|
37249
37473
|
const channelsBlock = channels.length === 0 ? "No channels connected.\n" : renderTable([
|
|
37250
|
-
["TYPE", "IDENTIFIER"],
|
|
37474
|
+
["TYPE", "IDENTIFIER", "MODE"],
|
|
37251
37475
|
...channels.map(
|
|
37252
37476
|
(c2) => (
|
|
37253
37477
|
// Telegram has no readable identifier — the bot token is write-only.
|
|
37254
|
-
|
|
37478
|
+
// Telegram is structurally shared-only.
|
|
37479
|
+
c2.type === "slack" /* Slack */ ? [
|
|
37480
|
+
"slack",
|
|
37481
|
+
c2.slackChannelId,
|
|
37482
|
+
c2.ambient ? "shared (ambient)" : c2.mode ?? "person-scoped"
|
|
37483
|
+
] : ["telegram", "\u2014", "shared"]
|
|
37255
37484
|
)
|
|
37256
37485
|
)
|
|
37257
37486
|
]);
|
|
@@ -37305,7 +37534,7 @@ function buildListCommand3(deps) {
|
|
|
37305
37534
|
// src/modules/channel/commands/precheck.ts
|
|
37306
37535
|
var UNAVAILABLE_MESSAGE = {
|
|
37307
37536
|
["slack" /* Slack */]: "Slack app token not configured",
|
|
37308
|
-
["telegram" /* Telegram */]: "Telegram
|
|
37537
|
+
["telegram" /* Telegram */]: "Telegram bot not configured"
|
|
37309
37538
|
};
|
|
37310
37539
|
async function ensureProviderAvailable(svc, provider, host) {
|
|
37311
37540
|
const res = await svc.available();
|
|
@@ -37323,11 +37552,17 @@ async function ensureProviderAvailable(svc, provider, host) {
|
|
|
37323
37552
|
// src/modules/channel/commands/slack-connect.ts
|
|
37324
37553
|
function buildSlackConnectCommand(deps) {
|
|
37325
37554
|
return new Command("connect").description("Bind a Slack channel to an Agent").argument("<agent>", "Agent Ref \u2014 name or 'agent-\u2026' ID").requiredOption("--channel-id <id>", "Slack channel id (e.g. C0123ABCD)").option(
|
|
37555
|
+
"--mode <mode>",
|
|
37556
|
+
"access mode: 'person-scoped' (default) or 'shared'"
|
|
37557
|
+
).option(
|
|
37558
|
+
"--ambient",
|
|
37559
|
+
"ambient mode (shared only): the agent reads along and may chime in without being mentioned"
|
|
37560
|
+
).option(
|
|
37326
37561
|
"--server <url>",
|
|
37327
37562
|
"override the configured server URL for this call"
|
|
37328
37563
|
).option("--json", "emit the updated ChannelConfig[] as JSON").addHelpText(
|
|
37329
37564
|
"after",
|
|
37330
|
-
"\nExamples:\n dam channel slack connect my-agent --channel-id C0123ABCD\n"
|
|
37565
|
+
"\nExamples:\n dam channel slack connect my-agent --channel-id C0123ABCD\n dam channel slack connect my-agent --channel-id C0123ABCD --mode shared\n dam channel slack connect my-agent --channel-id C0123ABCD --mode shared --ambient\n"
|
|
37331
37566
|
).action(
|
|
37332
37567
|
async (ref, opts) => {
|
|
37333
37568
|
const channelId = opts.channelId.trim();
|
|
@@ -37335,6 +37570,17 @@ function buildSlackConnectCommand(deps) {
|
|
|
37335
37570
|
process.stderr.write("error: --channel-id must not be empty\n");
|
|
37336
37571
|
process.exit(EXIT_INVALID_INPUT);
|
|
37337
37572
|
}
|
|
37573
|
+
if (opts.mode !== void 0 && opts.mode !== "shared" && opts.mode !== "person-scoped") {
|
|
37574
|
+
process.stderr.write(
|
|
37575
|
+
"error: --mode must be 'shared' or 'person-scoped'\n"
|
|
37576
|
+
);
|
|
37577
|
+
process.exit(EXIT_INVALID_INPUT);
|
|
37578
|
+
}
|
|
37579
|
+
const mode = opts.mode;
|
|
37580
|
+
if (opts.ambient && mode !== "shared") {
|
|
37581
|
+
process.stderr.write("error: --ambient requires --mode shared\n");
|
|
37582
|
+
process.exit(EXIT_INVALID_INPUT);
|
|
37583
|
+
}
|
|
37338
37584
|
const host = await resolveActiveHost(deps, {
|
|
37339
37585
|
flag: opts.server ? { server: opts.server } : void 0,
|
|
37340
37586
|
exitCodes: {
|
|
@@ -37352,7 +37598,12 @@ function buildSlackConnectCommand(deps) {
|
|
|
37352
37598
|
}
|
|
37353
37599
|
const svc = deps.createChannelService(host);
|
|
37354
37600
|
await ensureProviderAvailable(svc, "slack" /* Slack */, host);
|
|
37355
|
-
const res = await svc.connectSlack(
|
|
37601
|
+
const res = await svc.connectSlack(
|
|
37602
|
+
resolved.value.id,
|
|
37603
|
+
channelId,
|
|
37604
|
+
mode,
|
|
37605
|
+
opts.ambient
|
|
37606
|
+
);
|
|
37356
37607
|
if (!res.ok) {
|
|
37357
37608
|
if (res.error.kind === "channel-conflict") {
|
|
37358
37609
|
process.stderr.write(
|
|
@@ -37368,17 +37619,54 @@ function buildSlackConnectCommand(deps) {
|
|
|
37368
37619
|
printServiceError(res.error, host);
|
|
37369
37620
|
process.exit(EXIT_RUNTIME_FAILURE);
|
|
37370
37621
|
}
|
|
37622
|
+
if (mode === "shared") {
|
|
37623
|
+
const slackCh = res.value.find((c2) => c2.type === "slack" /* Slack */);
|
|
37624
|
+
if (!slackCh || slackCh.mode !== "shared") {
|
|
37625
|
+
const rolledBack = await svc.disconnectSlack(resolved.value.id);
|
|
37626
|
+
if (rolledBack.ok) {
|
|
37627
|
+
process.stderr.write(
|
|
37628
|
+
"error: this server does not support shared access mode \u2014 binding rolled back\n"
|
|
37629
|
+
);
|
|
37630
|
+
} else {
|
|
37631
|
+
process.stderr.write(
|
|
37632
|
+
"error: this server does not support shared access mode, and rolling the binding back failed \u2014 the channel is still bound in person-scoped mode; disconnect it manually\n"
|
|
37633
|
+
);
|
|
37634
|
+
printServiceError(rolledBack.error, host);
|
|
37635
|
+
}
|
|
37636
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
37637
|
+
}
|
|
37638
|
+
}
|
|
37639
|
+
if (opts.ambient) {
|
|
37640
|
+
const slackCh = res.value.find((c2) => c2.type === "slack" /* Slack */);
|
|
37641
|
+
if (slackCh?.type === "slack" /* Slack */ && !slackCh.ambient) {
|
|
37642
|
+
process.stderr.write(
|
|
37643
|
+
"error: this server does not support ambient mode \u2014 the channel is connected in shared mode without it\n"
|
|
37644
|
+
);
|
|
37645
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
37646
|
+
}
|
|
37647
|
+
}
|
|
37371
37648
|
if (opts.json) {
|
|
37372
37649
|
process.stdout.write(`${JSON.stringify(res.value)}
|
|
37373
37650
|
`);
|
|
37374
37651
|
} else {
|
|
37375
37652
|
process.stdout.write(
|
|
37376
|
-
`\u2713 Slack channel ${channelId} connected to ${resolved.value.name}.
|
|
37653
|
+
`\u2713 Slack channel ${channelId} connected to ${resolved.value.name}${mode === "shared" ? opts.ambient ? " in shared mode with ambient on" : " in shared mode" : ""}.
|
|
37377
37654
|
`
|
|
37378
37655
|
);
|
|
37379
|
-
|
|
37380
|
-
|
|
37381
|
-
|
|
37656
|
+
if (opts.ambient) {
|
|
37657
|
+
process.stderr.write(
|
|
37658
|
+
"note: the agent reads along in this channel and may chime in without being mentioned; the channel gets a visible notice\n"
|
|
37659
|
+
);
|
|
37660
|
+
}
|
|
37661
|
+
if (mode === "shared") {
|
|
37662
|
+
process.stderr.write(
|
|
37663
|
+
"note: everyone in the channel drives this agent under its credentials; your Terms-of-Use acceptance covers every turn\n"
|
|
37664
|
+
);
|
|
37665
|
+
} else {
|
|
37666
|
+
process.stderr.write(
|
|
37667
|
+
"hint: users must run `/platform login` inside Slack before they can drive this agent\n"
|
|
37668
|
+
);
|
|
37669
|
+
}
|
|
37382
37670
|
}
|
|
37383
37671
|
process.exit(EXIT_SUCCESS);
|
|
37384
37672
|
}
|
|
@@ -37430,131 +37718,19 @@ function buildSlackDisconnectCommand(deps) {
|
|
|
37430
37718
|
});
|
|
37431
37719
|
}
|
|
37432
37720
|
|
|
37433
|
-
// src/modules/channel/commands/telegram-connect.ts
|
|
37434
|
-
function buildTelegramConnectCommand(deps) {
|
|
37435
|
-
return new Command("connect").description("Bind a Telegram bot to an Agent").argument("<agent>", "Agent Ref \u2014 name or 'agent-\u2026' ID").option(
|
|
37436
|
-
"--bot-token <token>",
|
|
37437
|
-
"bot token from @BotFather (prompted, masked, if omitted on a TTY)"
|
|
37438
|
-
).option(
|
|
37439
|
-
"--server <url>",
|
|
37440
|
-
"override the configured server URL for this call"
|
|
37441
|
-
).option("--json", "emit the updated ChannelConfig[] as JSON").addHelpText(
|
|
37442
|
-
"after",
|
|
37443
|
-
"\nExamples:\n dam channel telegram connect my-agent\n dam channel telegram connect my-agent --bot-token 123:ABC\n"
|
|
37444
|
-
).action(
|
|
37445
|
-
async (ref, opts) => {
|
|
37446
|
-
const host = await resolveActiveHost(deps, {
|
|
37447
|
-
flag: opts.server ? { server: opts.server } : void 0,
|
|
37448
|
-
exitCodes: {
|
|
37449
|
-
runtimeFailure: EXIT_RUNTIME_FAILURE,
|
|
37450
|
-
belowFloor: EXIT_BELOW_FLOOR
|
|
37451
|
-
}
|
|
37452
|
-
});
|
|
37453
|
-
const resolver = createAgentResolver({
|
|
37454
|
-
agentService: deps.createAgentService(host)
|
|
37455
|
-
});
|
|
37456
|
-
const resolved = await resolver.resolve(ref);
|
|
37457
|
-
if (!resolved.ok) {
|
|
37458
|
-
printResolveError(resolved.error, host);
|
|
37459
|
-
process.exit(exitCodeForResolveError(resolved.error));
|
|
37460
|
-
}
|
|
37461
|
-
const token = await resolveToken(opts);
|
|
37462
|
-
const svc = deps.createChannelService(host);
|
|
37463
|
-
await ensureProviderAvailable(svc, "telegram" /* Telegram */, host);
|
|
37464
|
-
const res = await svc.connectTelegram(resolved.value.id, token);
|
|
37465
|
-
if (!res.ok) {
|
|
37466
|
-
if (res.error.kind === "channel-precondition" || res.error.kind === "invalid-input") {
|
|
37467
|
-
process.stderr.write(`error: ${res.error.message}
|
|
37468
|
-
`);
|
|
37469
|
-
process.exit(EXIT_INVALID_INPUT);
|
|
37470
|
-
}
|
|
37471
|
-
printServiceError(res.error, host);
|
|
37472
|
-
process.exit(EXIT_RUNTIME_FAILURE);
|
|
37473
|
-
}
|
|
37474
|
-
if (opts.json) {
|
|
37475
|
-
process.stdout.write(`${JSON.stringify(res.value)}
|
|
37476
|
-
`);
|
|
37477
|
-
} else {
|
|
37478
|
-
process.stdout.write(
|
|
37479
|
-
`\u2713 Telegram bot connected to ${resolved.value.name}.
|
|
37480
|
-
`
|
|
37481
|
-
);
|
|
37482
|
-
}
|
|
37483
|
-
process.exit(EXIT_SUCCESS);
|
|
37484
|
-
}
|
|
37485
|
-
);
|
|
37486
|
-
}
|
|
37487
|
-
async function resolveToken(opts) {
|
|
37488
|
-
const flag = opts.botToken?.trim();
|
|
37489
|
-
if (flag) return flag;
|
|
37490
|
-
if (!process.stdin.isTTY) {
|
|
37491
|
-
process.stderr.write("error: --bot-token is required on a non-TTY\n");
|
|
37492
|
-
process.exit(EXIT_INVALID_INPUT);
|
|
37493
|
-
}
|
|
37494
|
-
const answer = await Ce({
|
|
37495
|
-
message: "Telegram bot token (from @BotFather)",
|
|
37496
|
-
validate: (v2) => v2 && v2.trim().length > 0 ? void 0 : "Required"
|
|
37497
|
-
});
|
|
37498
|
-
if (q(answer)) exitCancelled({ json: opts.json });
|
|
37499
|
-
return String(answer).trim();
|
|
37500
|
-
}
|
|
37501
|
-
|
|
37502
|
-
// src/modules/channel/commands/telegram-disconnect.ts
|
|
37503
|
-
function buildTelegramDisconnectCommand(deps) {
|
|
37504
|
-
return new Command("disconnect").description(
|
|
37505
|
-
"Unbind an Agent's Telegram bot (deletes its k8s Secret). Idempotent \u2014 a not-connected agent exits 0."
|
|
37506
|
-
).argument("<agent>", "Agent Ref \u2014 name or 'agent-\u2026' ID").option(
|
|
37507
|
-
"--server <url>",
|
|
37508
|
-
"override the configured server URL for this call"
|
|
37509
|
-
).option("--json", "emit the updated ChannelConfig[] as JSON").addHelpText(
|
|
37510
|
-
"after",
|
|
37511
|
-
"\nExamples:\n dam channel telegram disconnect my-agent\n"
|
|
37512
|
-
).action(async (ref, opts) => {
|
|
37513
|
-
const host = await resolveActiveHost(deps, {
|
|
37514
|
-
flag: opts.server ? { server: opts.server } : void 0,
|
|
37515
|
-
exitCodes: {
|
|
37516
|
-
runtimeFailure: EXIT_RUNTIME_FAILURE,
|
|
37517
|
-
belowFloor: EXIT_BELOW_FLOOR
|
|
37518
|
-
}
|
|
37519
|
-
});
|
|
37520
|
-
const resolver = createAgentResolver({
|
|
37521
|
-
agentService: deps.createAgentService(host)
|
|
37522
|
-
});
|
|
37523
|
-
const resolved = await resolver.resolve(ref);
|
|
37524
|
-
if (!resolved.ok) {
|
|
37525
|
-
printResolveError(resolved.error, host);
|
|
37526
|
-
process.exit(exitCodeForResolveError(resolved.error));
|
|
37527
|
-
}
|
|
37528
|
-
const svc = deps.createChannelService(host);
|
|
37529
|
-
const res = await svc.disconnectTelegram(resolved.value.id);
|
|
37530
|
-
if (!res.ok) {
|
|
37531
|
-
printServiceError(res.error, host);
|
|
37532
|
-
process.exit(EXIT_RUNTIME_FAILURE);
|
|
37533
|
-
}
|
|
37534
|
-
if (opts.json) {
|
|
37535
|
-
process.stdout.write(`${JSON.stringify(res.value)}
|
|
37536
|
-
`);
|
|
37537
|
-
} else {
|
|
37538
|
-
process.stdout.write(
|
|
37539
|
-
`\u2713 Telegram disconnected from ${resolved.value.name}.
|
|
37540
|
-
`
|
|
37541
|
-
);
|
|
37542
|
-
}
|
|
37543
|
-
process.exit(EXIT_SUCCESS);
|
|
37544
|
-
});
|
|
37545
|
-
}
|
|
37546
|
-
|
|
37547
37721
|
// src/modules/channel/services/channel-service.ts
|
|
37548
37722
|
function createChannelService(deps) {
|
|
37549
37723
|
return {
|
|
37550
37724
|
async available() {
|
|
37551
37725
|
return trpcCall(() => deps.trpc.channels.available.query());
|
|
37552
37726
|
},
|
|
37553
|
-
async connectSlack(id, slackChannelId) {
|
|
37727
|
+
async connectSlack(id, slackChannelId, mode, ambient) {
|
|
37554
37728
|
try {
|
|
37555
37729
|
const agent = await deps.trpc.agents.connectSlack.mutate({
|
|
37556
37730
|
id,
|
|
37557
|
-
slackChannelId
|
|
37731
|
+
slackChannelId,
|
|
37732
|
+
...mode ? { mode } : {},
|
|
37733
|
+
...ambient ? { ambient: true } : {}
|
|
37558
37734
|
});
|
|
37559
37735
|
return ok2(agent.channels);
|
|
37560
37736
|
} catch (e2) {
|
|
@@ -37574,29 +37750,6 @@ function createChannelService(deps) {
|
|
|
37574
37750
|
const agent = await deps.trpc.agents.disconnectSlack.mutate({ id });
|
|
37575
37751
|
return agent.channels;
|
|
37576
37752
|
});
|
|
37577
|
-
},
|
|
37578
|
-
async connectTelegram(id, botToken) {
|
|
37579
|
-
try {
|
|
37580
|
-
const agent = await deps.trpc.agents.connectTelegram.mutate({
|
|
37581
|
-
id,
|
|
37582
|
-
botToken
|
|
37583
|
-
});
|
|
37584
|
-
return ok2(agent.channels);
|
|
37585
|
-
} catch (e2) {
|
|
37586
|
-
const code = e2?.data?.code;
|
|
37587
|
-
const message = e2 instanceof Error ? e2.message : String(e2);
|
|
37588
|
-
if (code === "PRECONDITION_FAILED")
|
|
37589
|
-
return err2({ kind: "channel-precondition", message });
|
|
37590
|
-
if (code === "BAD_REQUEST")
|
|
37591
|
-
return err2({ kind: "invalid-input", message });
|
|
37592
|
-
return classifyTrpcError(e2);
|
|
37593
|
-
}
|
|
37594
|
-
},
|
|
37595
|
-
async disconnectTelegram(id) {
|
|
37596
|
-
return trpcCall(async () => {
|
|
37597
|
-
const agent = await deps.trpc.agents.disconnectTelegram.mutate({ id });
|
|
37598
|
-
return agent.channels;
|
|
37599
|
-
});
|
|
37600
37753
|
}
|
|
37601
37754
|
};
|
|
37602
37755
|
}
|
|
@@ -37612,7 +37765,7 @@ function composeChannelModule(opts) {
|
|
|
37612
37765
|
createChannelService: createService
|
|
37613
37766
|
};
|
|
37614
37767
|
const parent = new Command("channel").description(
|
|
37615
|
-
"Manage messenger channel bindings (
|
|
37768
|
+
"Manage messenger channel bindings (Telegram chats bind in-chat via /login)"
|
|
37616
37769
|
);
|
|
37617
37770
|
parent.addCommand(
|
|
37618
37771
|
buildAvailableCommand({
|
|
@@ -37634,12 +37787,6 @@ function composeChannelModule(opts) {
|
|
|
37634
37787
|
slack.addCommand(buildSlackConnectCommand(agentScoped));
|
|
37635
37788
|
slack.addCommand(buildSlackDisconnectCommand(agentScoped));
|
|
37636
37789
|
parent.addCommand(slack);
|
|
37637
|
-
const telegram = new Command("telegram").description(
|
|
37638
|
-
"Bind or unbind an Agent's Telegram bot"
|
|
37639
|
-
);
|
|
37640
|
-
telegram.addCommand(buildTelegramConnectCommand(agentScoped));
|
|
37641
|
-
telegram.addCommand(buildTelegramDisconnectCommand(agentScoped));
|
|
37642
|
-
parent.addCommand(telegram);
|
|
37643
37790
|
const allowScoped = {
|
|
37644
37791
|
compatService: opts.compatService,
|
|
37645
37792
|
configService: opts.configService,
|
|
@@ -39647,6 +39794,7 @@ function createAcpSessionClient(opts) {
|
|
|
39647
39794
|
}
|
|
39648
39795
|
|
|
39649
39796
|
// src/modules/chat/infrastructure/terminal-bridge.ts
|
|
39797
|
+
var TERMINAL_MODE_RESET = "\x1B[<u\x1B[?1049l\x1B[?1000;1002;1003;1005;1006;1015;1016l\x1B[?1004l\x1B[?2004l\x1B[?25h\x1B[0m";
|
|
39650
39798
|
function connectTerminalBridge({
|
|
39651
39799
|
host,
|
|
39652
39800
|
token,
|
|
@@ -39680,6 +39828,7 @@ function connectTerminalBridge({
|
|
|
39680
39828
|
} catch {
|
|
39681
39829
|
}
|
|
39682
39830
|
stdin.pause();
|
|
39831
|
+
stdout.write(TERMINAL_MODE_RESET);
|
|
39683
39832
|
if (ws.readyState === wrapper_default.OPEN || ws.readyState === wrapper_default.CONNECTING)
|
|
39684
39833
|
ws.close();
|
|
39685
39834
|
resolve4(result);
|
|
@@ -40174,7 +40323,7 @@ function createProcessEnvReader() {
|
|
|
40174
40323
|
|
|
40175
40324
|
// src/modules/cli/infrastructure/package-version.ts
|
|
40176
40325
|
function readPackageVersion() {
|
|
40177
|
-
return true ? "0.2.
|
|
40326
|
+
return true ? "0.2.9-rc1" : DEV_VERSION;
|
|
40178
40327
|
}
|
|
40179
40328
|
|
|
40180
40329
|
// src/modules/cli/infrastructure/version-probe.ts
|
|
@@ -40410,7 +40559,13 @@ function buildConnectCommand(deps) {
|
|
|
40410
40559
|
).option(
|
|
40411
40560
|
"--audience <audience>",
|
|
40412
40561
|
"input: OAuth audience (client credentials)"
|
|
40413
|
-
).option("--app-slug <slug>", "input: GitHub App slug").option("--
|
|
40562
|
+
).option("--app-slug <slug>", "input: GitHub App slug").option("--app-id <id>", "input: GitHub App ID (GitHub App installation)").option(
|
|
40563
|
+
"--installation-id <id>",
|
|
40564
|
+
"input: GitHub App installation ID (GitHub App installation)"
|
|
40565
|
+
).option(
|
|
40566
|
+
"--private-key <pem>",
|
|
40567
|
+
'input: GitHub App private key \u2014 PEM or base64; use --private-key "$(cat app.pem)" (GitHub App installation)'
|
|
40568
|
+
).option("--header-name <name>", "input: header name").option("--value-format <format>", "input: header value format").option(
|
|
40414
40569
|
"--env-name <name>",
|
|
40415
40570
|
"input: expose the credential to the agent as this env var (custom header credentials)"
|
|
40416
40571
|
).option("--value <value>", "input: header secret value").option(
|
|
@@ -40433,7 +40588,7 @@ function buildConnectCommand(deps) {
|
|
|
40433
40588
|
String(DEFAULT_TIMEOUT_SECONDS3)
|
|
40434
40589
|
).addHelpText(
|
|
40435
40590
|
"after",
|
|
40436
|
-
|
|
40591
|
+
'\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 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'
|
|
40437
40592
|
).action(async (providerOrUrl, opts) => {
|
|
40438
40593
|
const json2 = opts.json ?? false;
|
|
40439
40594
|
const timeoutSeconds = parseTimeout2(opts.timeout);
|
|
@@ -40655,8 +40810,9 @@ async function collectInputs(template, opts, json2) {
|
|
|
40655
40810
|
}
|
|
40656
40811
|
for (const input of missing) {
|
|
40657
40812
|
const prompt = input.secret ? Ce : Re;
|
|
40813
|
+
const label = input.label ?? labelFor(input.name);
|
|
40658
40814
|
const answer = await prompt({
|
|
40659
|
-
message:
|
|
40815
|
+
message: input.hint ? `${label} \u2014 ${input.hint}` : label,
|
|
40660
40816
|
validate: (v2) => v2 && v2.trim().length > 0 ? void 0 : "Required"
|
|
40661
40817
|
});
|
|
40662
40818
|
if (q(answer)) exitCancelled({ json: json2 });
|
|
@@ -40695,6 +40851,25 @@ function buildPayload(template, name, values) {
|
|
|
40695
40851
|
...v2("valueFormat") ? { valueFormat: v2("valueFormat") } : {},
|
|
40696
40852
|
...v2("envName") ? { envName: v2("envName") } : {}
|
|
40697
40853
|
};
|
|
40854
|
+
case "github-app": {
|
|
40855
|
+
const appId = v2("appId");
|
|
40856
|
+
const installationId = v2("installationId");
|
|
40857
|
+
const privateKey = v2("privateKey");
|
|
40858
|
+
if (!appId) return { error: "the App ID is required (--app-id)" };
|
|
40859
|
+
if (!installationId) {
|
|
40860
|
+
return { error: "the installation ID is required (--installation-id)" };
|
|
40861
|
+
}
|
|
40862
|
+
if (!privateKey) {
|
|
40863
|
+
return { error: "the private key is required (--private-key)" };
|
|
40864
|
+
}
|
|
40865
|
+
return {
|
|
40866
|
+
...common2,
|
|
40867
|
+
authKind: "github-app",
|
|
40868
|
+
appId,
|
|
40869
|
+
installationId,
|
|
40870
|
+
privateKey
|
|
40871
|
+
};
|
|
40872
|
+
}
|
|
40698
40873
|
case "header": {
|
|
40699
40874
|
const value = v2("value");
|
|
40700
40875
|
if (!value) return { error: "the secret value is required (--value)" };
|
|
@@ -40817,6 +40992,9 @@ var FIELD_LABELS = {
|
|
|
40817
40992
|
scopes: "Scopes (space-separated)",
|
|
40818
40993
|
audience: "Audience",
|
|
40819
40994
|
appSlug: "GitHub App slug",
|
|
40995
|
+
appId: "GitHub App ID",
|
|
40996
|
+
installationId: "GitHub App installation ID",
|
|
40997
|
+
privateKey: "GitHub App private key (PEM)",
|
|
40820
40998
|
envName: "Env var name",
|
|
40821
40999
|
caData: "Cluster CA certificate"
|
|
40822
41000
|
};
|
|
@@ -44230,6 +44408,12 @@ function createSkillsService(deps) {
|
|
|
44230
44408
|
const message = e2.message.replace(/\nplatform-cta:\S+/, "").trim();
|
|
44231
44409
|
return err2({ kind: "source-needs-connection", message, cta });
|
|
44232
44410
|
}
|
|
44411
|
+
if (e2?.data?.code === "FORBIDDEN") {
|
|
44412
|
+
return err2({
|
|
44413
|
+
kind: "source-needs-connection",
|
|
44414
|
+
message: e2 instanceof Error ? e2.message : String(e2)
|
|
44415
|
+
});
|
|
44416
|
+
}
|
|
44233
44417
|
return classifyWakeError(e2);
|
|
44234
44418
|
}
|
|
44235
44419
|
},
|
|
@@ -45159,6 +45343,248 @@ function composeTemplateModule(opts) {
|
|
|
45159
45343
|
};
|
|
45160
45344
|
}
|
|
45161
45345
|
|
|
45346
|
+
// src/modules/terms/commands/accept.ts
|
|
45347
|
+
function buildAcceptCommand(deps) {
|
|
45348
|
+
return new Command("accept").description(
|
|
45349
|
+
"Accept the current Terms of Use \u2014 interactive on a TTY, use --yes for CI/headless"
|
|
45350
|
+
).option(
|
|
45351
|
+
"--yes",
|
|
45352
|
+
"accept without the interactive confirmation (required on a non-TTY)"
|
|
45353
|
+
).option(
|
|
45354
|
+
"--expect-version <version>",
|
|
45355
|
+
"assert the version you reviewed; fails if it differs from the server's current version (not named --version, which is reserved for the CLI's own version)"
|
|
45356
|
+
).option(
|
|
45357
|
+
"--server <url>",
|
|
45358
|
+
"override the configured server URL for this call"
|
|
45359
|
+
).option("--json", "emit the acceptance result as JSON").action(
|
|
45360
|
+
async (opts) => {
|
|
45361
|
+
const host = await resolveActiveHost(deps, {
|
|
45362
|
+
flag: opts.server ? { server: opts.server } : void 0,
|
|
45363
|
+
exitCodes: {
|
|
45364
|
+
runtimeFailure: EXIT_RUNTIME_FAILURE,
|
|
45365
|
+
belowFloor: EXIT_BELOW_FLOOR
|
|
45366
|
+
}
|
|
45367
|
+
});
|
|
45368
|
+
if (!opts.yes && !process.stdin.isTTY) {
|
|
45369
|
+
process.stderr.write(
|
|
45370
|
+
"error: refusing to accept the Terms of Use non-interactively without --yes\nhint: re-run with --yes to accept in a script or CI\n"
|
|
45371
|
+
);
|
|
45372
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
45373
|
+
}
|
|
45374
|
+
const service = deps.createTermsService(host);
|
|
45375
|
+
const doc = await service.document();
|
|
45376
|
+
if (!doc.ok) {
|
|
45377
|
+
printServiceError(doc.error, host);
|
|
45378
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
45379
|
+
}
|
|
45380
|
+
const currentVersion = doc.value.version;
|
|
45381
|
+
if (opts.expectVersion && opts.expectVersion !== currentVersion) {
|
|
45382
|
+
process.stderr.write(
|
|
45383
|
+
`error: reviewed version ${opts.expectVersion} does not match the server's current version ${currentVersion}; re-review before accepting
|
|
45384
|
+
`
|
|
45385
|
+
);
|
|
45386
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
45387
|
+
}
|
|
45388
|
+
if (!opts.yes) {
|
|
45389
|
+
process.stderr.write(
|
|
45390
|
+
`Terms of Use \u2014 version ${currentVersion}
|
|
45391
|
+
|
|
45392
|
+
${doc.value.text}
|
|
45393
|
+
|
|
45394
|
+
`
|
|
45395
|
+
);
|
|
45396
|
+
if (!await confirm("Accept the Terms of Use?", {
|
|
45397
|
+
timeoutMs: 15 * 6e4
|
|
45398
|
+
}))
|
|
45399
|
+
exitCancelled({ json: opts.json });
|
|
45400
|
+
}
|
|
45401
|
+
const accepted = await service.accept(currentVersion);
|
|
45402
|
+
if (!accepted.ok) {
|
|
45403
|
+
if (accepted.error.kind === "transport" && accepted.error.serverCode === "PRECONDITION_FAILED") {
|
|
45404
|
+
process.stderr.write(
|
|
45405
|
+
"error: the Terms of Use changed while you were reviewing; re-run `dam terms accept` to review the current version\n"
|
|
45406
|
+
);
|
|
45407
|
+
} else {
|
|
45408
|
+
printServiceError(accepted.error, host);
|
|
45409
|
+
}
|
|
45410
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
45411
|
+
}
|
|
45412
|
+
if (opts.json) {
|
|
45413
|
+
return writeStdoutAndExit(
|
|
45414
|
+
`${JSON.stringify({ accepted: true, version: currentVersion })}
|
|
45415
|
+
`,
|
|
45416
|
+
EXIT_SUCCESS
|
|
45417
|
+
);
|
|
45418
|
+
}
|
|
45419
|
+
return writeStdoutAndExit(
|
|
45420
|
+
`Accepted Terms of Use ${currentVersion}.
|
|
45421
|
+
`,
|
|
45422
|
+
EXIT_SUCCESS
|
|
45423
|
+
);
|
|
45424
|
+
}
|
|
45425
|
+
);
|
|
45426
|
+
}
|
|
45427
|
+
|
|
45428
|
+
// src/modules/terms/commands/show.ts
|
|
45429
|
+
function buildShowCommand(deps) {
|
|
45430
|
+
return new Command("show").description(
|
|
45431
|
+
"Print the current Terms of Use text, version, and your acceptance state"
|
|
45432
|
+
).option(
|
|
45433
|
+
"--server <url>",
|
|
45434
|
+
"override the configured server URL for this call"
|
|
45435
|
+
).option("--json", "emit the raw Terms of Use document as JSON").action(async (opts) => {
|
|
45436
|
+
const host = await resolveActiveHost(deps, {
|
|
45437
|
+
flag: opts.server ? { server: opts.server } : void 0,
|
|
45438
|
+
exitCodes: {
|
|
45439
|
+
runtimeFailure: EXIT_RUNTIME_FAILURE,
|
|
45440
|
+
belowFloor: EXIT_BELOW_FLOOR
|
|
45441
|
+
}
|
|
45442
|
+
});
|
|
45443
|
+
const service = deps.createTermsService(host);
|
|
45444
|
+
const [doc, latest] = await Promise.all([
|
|
45445
|
+
service.document(),
|
|
45446
|
+
service.latestAcceptance()
|
|
45447
|
+
]);
|
|
45448
|
+
if (!doc.ok) {
|
|
45449
|
+
printServiceError(doc.error, host);
|
|
45450
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
45451
|
+
}
|
|
45452
|
+
if (!latest.ok) {
|
|
45453
|
+
printServiceError(latest.error, host);
|
|
45454
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
45455
|
+
}
|
|
45456
|
+
if (opts.json) {
|
|
45457
|
+
return writeStdoutAndExit(
|
|
45458
|
+
`${JSON.stringify(doc.value)}
|
|
45459
|
+
`,
|
|
45460
|
+
EXIT_SUCCESS
|
|
45461
|
+
);
|
|
45462
|
+
}
|
|
45463
|
+
const acceptState = !latest.value ? "Not accepted." : latest.value.version === doc.value.version ? `Accepted on ${new Date(latest.value.acceptedAt).toISOString()}.` : `You accepted version ${latest.value.version}; version ${doc.value.version} is current and not yet accepted.`;
|
|
45464
|
+
return writeStdoutAndExit(
|
|
45465
|
+
`Terms of Use \u2014 version ${doc.value.version}
|
|
45466
|
+
${acceptState}
|
|
45467
|
+
|
|
45468
|
+
${doc.value.text}
|
|
45469
|
+
`,
|
|
45470
|
+
EXIT_SUCCESS
|
|
45471
|
+
);
|
|
45472
|
+
});
|
|
45473
|
+
}
|
|
45474
|
+
|
|
45475
|
+
// src/modules/terms/commands/status.ts
|
|
45476
|
+
function buildStatusCommand2(deps) {
|
|
45477
|
+
return new Command("status").description(
|
|
45478
|
+
"Check whether you've accepted the current Terms of Use \u2014 no text dump; exits non-zero when not accepted, so it works as a CI gate"
|
|
45479
|
+
).option(
|
|
45480
|
+
"--server <url>",
|
|
45481
|
+
"override the configured server URL for this call"
|
|
45482
|
+
).option("--json", "emit the acceptance state as JSON").action(async (opts) => {
|
|
45483
|
+
const host = await resolveActiveHost(deps, {
|
|
45484
|
+
flag: opts.server ? { server: opts.server } : void 0,
|
|
45485
|
+
exitCodes: {
|
|
45486
|
+
runtimeFailure: EXIT_RUNTIME_FAILURE,
|
|
45487
|
+
belowFloor: EXIT_BELOW_FLOOR
|
|
45488
|
+
}
|
|
45489
|
+
});
|
|
45490
|
+
const service = deps.createTermsService(host);
|
|
45491
|
+
const [current, latest] = await Promise.all([
|
|
45492
|
+
service.current(),
|
|
45493
|
+
service.latestAcceptance()
|
|
45494
|
+
]);
|
|
45495
|
+
if (!current.ok) {
|
|
45496
|
+
printServiceError(current.error, host);
|
|
45497
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
45498
|
+
}
|
|
45499
|
+
if (!latest.ok) {
|
|
45500
|
+
printServiceError(latest.error, host);
|
|
45501
|
+
process.exit(EXIT_RUNTIME_FAILURE);
|
|
45502
|
+
}
|
|
45503
|
+
const acceptedVersion = latest.value?.version ?? null;
|
|
45504
|
+
const accepted = acceptedVersion === current.value.version;
|
|
45505
|
+
const exitCode = accepted ? EXIT_SUCCESS : EXIT_TERMS_NOT_ACCEPTED;
|
|
45506
|
+
if (opts.json) {
|
|
45507
|
+
return writeStdoutAndExit(
|
|
45508
|
+
`${JSON.stringify({ currentVersion: current.value.version, acceptedVersion, accepted })}
|
|
45509
|
+
`,
|
|
45510
|
+
exitCode
|
|
45511
|
+
);
|
|
45512
|
+
}
|
|
45513
|
+
const line = accepted ? `Terms of Use ${current.value.version}: accepted.` : acceptedVersion ? `Terms of Use ${current.value.version}: NOT accepted (you accepted ${acceptedVersion}).` : `Terms of Use ${current.value.version}: NOT accepted (no acceptance on record).`;
|
|
45514
|
+
return writeStdoutAndExit(`${line}
|
|
45515
|
+
`, exitCode);
|
|
45516
|
+
});
|
|
45517
|
+
}
|
|
45518
|
+
|
|
45519
|
+
// src/modules/terms/services/terms-service.ts
|
|
45520
|
+
function createTermsService(deps) {
|
|
45521
|
+
const doFetch = deps.fetch ?? fetch;
|
|
45522
|
+
const base = deps.host.replace(/\/+$/, "");
|
|
45523
|
+
return {
|
|
45524
|
+
async document() {
|
|
45525
|
+
let res;
|
|
45526
|
+
try {
|
|
45527
|
+
res = await doFetch(`${base}/api/terms`);
|
|
45528
|
+
} catch (e2) {
|
|
45529
|
+
return err2({
|
|
45530
|
+
kind: "transport",
|
|
45531
|
+
reason: e2 instanceof Error ? e2.message : "cannot reach server"
|
|
45532
|
+
});
|
|
45533
|
+
}
|
|
45534
|
+
if (!res.ok)
|
|
45535
|
+
return err2({
|
|
45536
|
+
kind: "transport",
|
|
45537
|
+
reason: `GET /api/terms returned ${res.status}`
|
|
45538
|
+
});
|
|
45539
|
+
let body;
|
|
45540
|
+
try {
|
|
45541
|
+
body = await res.json();
|
|
45542
|
+
} catch {
|
|
45543
|
+
return err2({
|
|
45544
|
+
kind: "transport",
|
|
45545
|
+
reason: "malformed Terms of Use document from server"
|
|
45546
|
+
});
|
|
45547
|
+
}
|
|
45548
|
+
const parsed = termsDocumentSchema.safeParse(body);
|
|
45549
|
+
if (!parsed.success)
|
|
45550
|
+
return err2({
|
|
45551
|
+
kind: "transport",
|
|
45552
|
+
reason: "malformed Terms of Use document from server"
|
|
45553
|
+
});
|
|
45554
|
+
return ok2(parsed.data);
|
|
45555
|
+
},
|
|
45556
|
+
async current() {
|
|
45557
|
+
return trpcCall(() => deps.trpc.terms.current.query());
|
|
45558
|
+
},
|
|
45559
|
+
async latestAcceptance() {
|
|
45560
|
+
return trpcCall(() => deps.trpc.terms.latestAcceptance.query());
|
|
45561
|
+
},
|
|
45562
|
+
async accept(version2) {
|
|
45563
|
+
return trpcCall(() => deps.trpc.terms.accept.mutate({ version: version2 }));
|
|
45564
|
+
}
|
|
45565
|
+
};
|
|
45566
|
+
}
|
|
45567
|
+
|
|
45568
|
+
// src/modules/terms/compose.ts
|
|
45569
|
+
function composeTermsModule(opts) {
|
|
45570
|
+
const createService = (host) => createTermsService({
|
|
45571
|
+
trpc: createTrpcClient({ host, tokenProvider: opts.tokenProvider }),
|
|
45572
|
+
host
|
|
45573
|
+
});
|
|
45574
|
+
const scoped = {
|
|
45575
|
+
compatService: opts.compatService,
|
|
45576
|
+
configService: opts.configService,
|
|
45577
|
+
createTermsService: createService
|
|
45578
|
+
};
|
|
45579
|
+
const parent = new Command("terms").description(
|
|
45580
|
+
"View and accept the deployment's Terms of Use"
|
|
45581
|
+
);
|
|
45582
|
+
parent.addCommand(buildShowCommand(scoped));
|
|
45583
|
+
parent.addCommand(buildStatusCommand2(scoped));
|
|
45584
|
+
parent.addCommand(buildAcceptCommand(scoped));
|
|
45585
|
+
return { commands: [parent] };
|
|
45586
|
+
}
|
|
45587
|
+
|
|
45162
45588
|
// src/compose.ts
|
|
45163
45589
|
function compose(opts = {}) {
|
|
45164
45590
|
const cli = composeCliModule({ configPath: opts.configPath });
|
|
@@ -45251,6 +45677,11 @@ function compose(opts = {}) {
|
|
|
45251
45677
|
compatService: cli.services.compatService,
|
|
45252
45678
|
createAgentService: agent.exports.createService
|
|
45253
45679
|
});
|
|
45680
|
+
const terms = composeTermsModule({
|
|
45681
|
+
tokenProvider: auth.exports.tokenProvider,
|
|
45682
|
+
configService: cli.services.configService,
|
|
45683
|
+
compatService: cli.services.compatService
|
|
45684
|
+
});
|
|
45254
45685
|
const program3 = new Command();
|
|
45255
45686
|
program3.name("dam").description("Command-line client for a Platform deployment").version(cli.cliVersion);
|
|
45256
45687
|
for (const command of cli.commands) program3.addCommand(command);
|
|
@@ -45268,6 +45699,7 @@ function compose(opts = {}) {
|
|
|
45268
45699
|
for (const command of ssh.commands) program3.addCommand(command);
|
|
45269
45700
|
for (const command of channel.commands) program3.addCommand(command);
|
|
45270
45701
|
for (const command of metrics.commands) program3.addCommand(command);
|
|
45702
|
+
for (const command of terms.commands) program3.addCommand(command);
|
|
45271
45703
|
return program3;
|
|
45272
45704
|
}
|
|
45273
45705
|
|
|
@@ -45278,9 +45710,7 @@ try {
|
|
|
45278
45710
|
} catch (err3) {
|
|
45279
45711
|
if (err3 instanceof TermsStaleAtTransportError) {
|
|
45280
45712
|
process.stderr.write(
|
|
45281
|
-
|
|
45282
|
-
hint: open ${err3.host} to accept
|
|
45283
|
-
`
|
|
45713
|
+
"error: Terms of Use acceptance required\nhint: run `dam terms accept` to review and accept\n"
|
|
45284
45714
|
);
|
|
45285
45715
|
process.exit(1);
|
|
45286
45716
|
}
|