@dench.com/cli 3.6.6-staging.386 → 3.8.0-staging.389
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/README.md +43 -44
- package/agent-config.ts +21 -57
- package/app-sdk.d.ts +367 -24
- package/chat-spawn.ts +11 -2
- package/chat.ts +1 -1
- package/context-settings.ts +86 -0
- package/crm.ts +92 -24
- package/cron.ts +19 -0
- package/dench.ts +318 -90
- package/email-inbox.ts +169 -0
- package/email.ts +103 -21
- package/environments.ts +694 -0
- package/lib/api-schemas.ts +160 -14
- package/lib/app-sdk-catalog.generated.ts +39 -19
- package/lib/bundled-references.ts +17 -0
- package/lib/cli-args.ts +30 -3
- package/lib/command-args.ts +252 -0
- package/lib/command-help.ts +93 -0
- package/lib/command-registry.ts +296 -10
- package/lib/environment-archive.ts +255 -0
- package/lib/environment-cli-args.ts +96 -0
- package/lib/environment-contract.ts +237 -0
- package/lib/environment-execution.ts +769 -0
- package/lib/environment-source.ts +165 -0
- package/lib/load-dev-env.mjs +3 -1
- package/lib/load-dev-env.test.mjs +26 -9
- package/lib/native-email-wait.ts +75 -0
- package/lib/parent-argv.ts +20 -0
- package/lib/public-error.ts +82 -0
- package/lib/references.generated.json +74 -0
- package/package.json +7 -3
- package/reference.ts +47 -0
- package/workspace-secrets.ts +231 -0
- package/agent.ts +0 -37
package/lib/api-schemas.ts
CHANGED
|
@@ -57,6 +57,48 @@ const nativeEmailCreate = z.object({
|
|
|
57
57
|
requestId: z.string(),
|
|
58
58
|
...nativeEmailContent,
|
|
59
59
|
});
|
|
60
|
+
const inboxHeader = z.object({
|
|
61
|
+
messageHandle: z.string(),
|
|
62
|
+
threadHandle: z.string(),
|
|
63
|
+
mailboxId: z.string(),
|
|
64
|
+
from: nativeEmailRecipient,
|
|
65
|
+
to: z.array(nativeEmailRecipient),
|
|
66
|
+
subject: z.string(),
|
|
67
|
+
at: z.number(),
|
|
68
|
+
dateSource: z.enum(["sentAt", "createdAt"]),
|
|
69
|
+
direction: z.enum(["inbound", "outbound"]),
|
|
70
|
+
status: z.string(),
|
|
71
|
+
hasAttachments: z.boolean(),
|
|
72
|
+
headersTruncated: z.boolean(),
|
|
73
|
+
});
|
|
74
|
+
const inboxCoverage = z.object({
|
|
75
|
+
source: z.literal("synced"),
|
|
76
|
+
scope: z.literal("mailbox_linked_messages"),
|
|
77
|
+
mailboxId: z.string(),
|
|
78
|
+
mailboxEmail: z.string(),
|
|
79
|
+
mailboxStatus: z.string(),
|
|
80
|
+
ingestionMode: z.string(),
|
|
81
|
+
phase: z.string(),
|
|
82
|
+
syncStatus: z.string().nullable(),
|
|
83
|
+
lastPolledAt: z.number().nullable(),
|
|
84
|
+
lastBackfillCompletedAt: z.number().nullable(),
|
|
85
|
+
oldestSeenAt: z.number().nullable(),
|
|
86
|
+
backfillStatus: z.string().nullable(),
|
|
87
|
+
backfillCapped: z.boolean(),
|
|
88
|
+
providerComplete: z.literal(false),
|
|
89
|
+
privacyLimited: z.boolean(),
|
|
90
|
+
});
|
|
91
|
+
const inboxPaging = {
|
|
92
|
+
limit: z.coerce.number().int().min(1).max(50).optional(),
|
|
93
|
+
cursor: z.string().optional(),
|
|
94
|
+
};
|
|
95
|
+
const inboxPage = z.object({
|
|
96
|
+
page: z.array(inboxHeader),
|
|
97
|
+
continueCursor: z.string().nullable(),
|
|
98
|
+
isDone: z.boolean(),
|
|
99
|
+
coverage: inboxCoverage,
|
|
100
|
+
order: z.literal("sentAt_desc_then_undated"),
|
|
101
|
+
});
|
|
60
102
|
const nativeEmailReceipt = z
|
|
61
103
|
.object({
|
|
62
104
|
ok: z.boolean(),
|
|
@@ -2118,7 +2160,7 @@ const composioToolRun = z.object({
|
|
|
2118
2160
|
tool_slug: z
|
|
2119
2161
|
.string()
|
|
2120
2162
|
.optional()
|
|
2121
|
-
.describe("Tool slug, e.g.
|
|
2163
|
+
.describe("Tool slug, e.g. SLACK_LIST_CHANNELS."),
|
|
2122
2164
|
arguments: z
|
|
2123
2165
|
.record(z.string(), z.unknown())
|
|
2124
2166
|
.optional()
|
|
@@ -3392,8 +3434,34 @@ export const requestSchemas: Record<string, ZodTypeAny> = {
|
|
|
3392
3434
|
)
|
|
3393
3435
|
.optional(),
|
|
3394
3436
|
}),
|
|
3437
|
+
"email.inbox.search": z.object({
|
|
3438
|
+
...inboxPaging,
|
|
3439
|
+
mailbox: z.string().optional(),
|
|
3440
|
+
from: z.string().min(1).max(500).optional(),
|
|
3441
|
+
to: z.string().min(1).max(500).optional(),
|
|
3442
|
+
subject: z.string().min(1).max(500).optional(),
|
|
3443
|
+
after: z.coerce
|
|
3444
|
+
.number()
|
|
3445
|
+
.optional()
|
|
3446
|
+
.describe(
|
|
3447
|
+
"Inclusive Unix milliseconds; missing sentAt falls back to createdAt.",
|
|
3448
|
+
),
|
|
3449
|
+
before: z.coerce
|
|
3450
|
+
.number()
|
|
3451
|
+
.optional()
|
|
3452
|
+
.describe("Exclusive Unix milliseconds."),
|
|
3453
|
+
direction: z.enum(["inbound", "outbound"]).optional(),
|
|
3454
|
+
}),
|
|
3455
|
+
"email.inbox.thread": z.object({ ...inboxPaging, threadHandle: z.string() }),
|
|
3456
|
+
"email.inbox.message": z.object({
|
|
3457
|
+
messageHandle: z.string(),
|
|
3458
|
+
format: z.enum(["text", "html"]).optional(),
|
|
3459
|
+
maxBytes: z.coerce.number().int().min(1).max(100000).optional(),
|
|
3460
|
+
}),
|
|
3395
3461
|
"email.drafts.create": nativeEmailCreate,
|
|
3396
|
-
"email.native.send": nativeEmailCreate
|
|
3462
|
+
"email.native.send": nativeEmailCreate.extend({
|
|
3463
|
+
to: z.array(nativeEmailRecipient).min(1),
|
|
3464
|
+
}),
|
|
3397
3465
|
"email.drafts.get": z.object({ draftId: z.string() }),
|
|
3398
3466
|
"email.drafts.senders": z.object({ organizationId: z.string().optional() }),
|
|
3399
3467
|
"email.drafts.update": z.object({
|
|
@@ -3516,6 +3584,10 @@ export const requestSchemas: Record<string, ZodTypeAny> = {
|
|
|
3516
3584
|
includeAutomated: z.boolean().optional(),
|
|
3517
3585
|
}),
|
|
3518
3586
|
"chat.new": z.object({
|
|
3587
|
+
environment: z
|
|
3588
|
+
.string()
|
|
3589
|
+
.regex(/^[a-z][a-z0-9-]{0,63}$/)
|
|
3590
|
+
.optional(),
|
|
3519
3591
|
prompt: z.string().describe("The user message that starts the turn."),
|
|
3520
3592
|
model: z.string().optional(),
|
|
3521
3593
|
fileContextPath: z.string().optional(),
|
|
@@ -3536,6 +3608,7 @@ export const requestSchemas: Record<string, ZodTypeAny> = {
|
|
|
3536
3608
|
|
|
3537
3609
|
// CRM objects
|
|
3538
3610
|
"crm.objects.list": noInput,
|
|
3611
|
+
"crm.objects.listCompact": noInput,
|
|
3539
3612
|
"crm.objects.get": z.object({ name: z.string() }),
|
|
3540
3613
|
"crm.objects.create": z.object({
|
|
3541
3614
|
name: z.string().describe("Object name (lowercased, singular)."),
|
|
@@ -3631,6 +3704,7 @@ export const requestSchemas: Record<string, ZodTypeAny> = {
|
|
|
3631
3704
|
|
|
3632
3705
|
// CRM fields
|
|
3633
3706
|
"crm.fields.list": z.object({ objectName: z.string() }),
|
|
3707
|
+
"crm.fields.listCompact": z.object({ objectName: z.string() }),
|
|
3634
3708
|
"crm.fields.create": z.object({
|
|
3635
3709
|
objectName: z.string(),
|
|
3636
3710
|
name: z.string(),
|
|
@@ -4163,6 +4237,18 @@ export const requestSchemas: Record<string, ZodTypeAny> = {
|
|
|
4163
4237
|
"Number field to total per bucket (e.g. Amount grouped by Stage). Exact at any table size.",
|
|
4164
4238
|
),
|
|
4165
4239
|
}),
|
|
4240
|
+
"crm.search.page": z.object({
|
|
4241
|
+
text: z.string().describe("Full-text query over readable entries."),
|
|
4242
|
+
objectName: z.string().optional(),
|
|
4243
|
+
select: z.array(z.string().min(1)).min(1).max(30).optional(),
|
|
4244
|
+
limit: z.coerce.number().int().min(1).max(100).optional(),
|
|
4245
|
+
cursor: z
|
|
4246
|
+
.string()
|
|
4247
|
+
.optional()
|
|
4248
|
+
.describe(
|
|
4249
|
+
"Use the preceding continueCursor, with the same query and projection.",
|
|
4250
|
+
),
|
|
4251
|
+
}),
|
|
4166
4252
|
"crm.search": z.object({
|
|
4167
4253
|
text: z.string().describe("Full-text query."),
|
|
4168
4254
|
objectName: z.string().optional().describe("Omit to search org-wide."),
|
|
@@ -5157,6 +5243,24 @@ export const responseSchemas: Record<string, ZodTypeAny> = {
|
|
|
5157
5243
|
|
|
5158
5244
|
// Workspace orientation
|
|
5159
5245
|
"workspace.context.sections": z.object({}).passthrough(),
|
|
5246
|
+
"email.inbox.search": inboxPage,
|
|
5247
|
+
"email.inbox.thread": inboxPage,
|
|
5248
|
+
"email.inbox.message": z.object({
|
|
5249
|
+
header: inboxHeader,
|
|
5250
|
+
coverage: inboxCoverage,
|
|
5251
|
+
body: z.object({
|
|
5252
|
+
format: z.enum(["text", "html"]),
|
|
5253
|
+
content: z.string(),
|
|
5254
|
+
truncated: z.boolean(),
|
|
5255
|
+
totalBytes: z.number(),
|
|
5256
|
+
}),
|
|
5257
|
+
recipients: z.object({
|
|
5258
|
+
to: z.array(nativeEmailRecipient),
|
|
5259
|
+
cc: z.array(nativeEmailRecipient),
|
|
5260
|
+
bcc: z.array(nativeEmailRecipient),
|
|
5261
|
+
truncated: z.boolean(),
|
|
5262
|
+
}),
|
|
5263
|
+
}),
|
|
5160
5264
|
"email.drafts.create": nativeEmailReceipt,
|
|
5161
5265
|
"email.drafts.get": nativeEmailReceipt,
|
|
5162
5266
|
"email.drafts.update": nativeEmailReceipt,
|
|
@@ -5283,6 +5387,18 @@ export const responseSchemas: Record<string, ZodTypeAny> = {
|
|
|
5283
5387
|
|
|
5284
5388
|
// CRM objects
|
|
5285
5389
|
"crm.objects.list": z.array(crmObjectDoc),
|
|
5390
|
+
"crm.objects.listCompact": z.array(
|
|
5391
|
+
z.object({
|
|
5392
|
+
_id: z.string(),
|
|
5393
|
+
name: z.string(),
|
|
5394
|
+
displayName: z.string(),
|
|
5395
|
+
description: z.string().optional(),
|
|
5396
|
+
entryCount: z.number().nullable(),
|
|
5397
|
+
countScope: z.enum(["workspace", "private_unknown"]),
|
|
5398
|
+
visibility: z.enum(["workspace", "owner_only", "owner_plus_members"]),
|
|
5399
|
+
archived: z.boolean(),
|
|
5400
|
+
}),
|
|
5401
|
+
),
|
|
5286
5402
|
"crm.objects.get": crmObjectDoc.nullable(),
|
|
5287
5403
|
"crm.objects.create": z.object({ id: z.string() }),
|
|
5288
5404
|
"crm.objects.update": okResponse,
|
|
@@ -5337,6 +5453,20 @@ export const responseSchemas: Record<string, ZodTypeAny> = {
|
|
|
5337
5453
|
|
|
5338
5454
|
// CRM fields
|
|
5339
5455
|
"crm.fields.list": z.array(crmFieldDoc),
|
|
5456
|
+
"crm.fields.listCompact": z.array(
|
|
5457
|
+
z.object({
|
|
5458
|
+
_id: z.string(),
|
|
5459
|
+
name: z.string(),
|
|
5460
|
+
type: z.string(),
|
|
5461
|
+
required: z.boolean(),
|
|
5462
|
+
readOnly: z.boolean(),
|
|
5463
|
+
defaultValue: z.string().optional(),
|
|
5464
|
+
enumValues: z.array(z.string()).optional(),
|
|
5465
|
+
enumMultiple: z.boolean(),
|
|
5466
|
+
relatedObjectId: z.string().optional(),
|
|
5467
|
+
relationshipType: z.string().optional(),
|
|
5468
|
+
}),
|
|
5469
|
+
),
|
|
5340
5470
|
"crm.fields.create": z.object({ id: z.string() }),
|
|
5341
5471
|
"crm.fields.update": okResponse,
|
|
5342
5472
|
"crm.fields.delete": okResponse,
|
|
@@ -5493,6 +5623,16 @@ export const responseSchemas: Record<string, ZodTypeAny> = {
|
|
|
5493
5623
|
sumNumber: z.number().optional(),
|
|
5494
5624
|
}),
|
|
5495
5625
|
),
|
|
5626
|
+
"crm.search.page": z.object({
|
|
5627
|
+
page: z.array(
|
|
5628
|
+
z.object({ _id: z.string(), objectId: z.string(), data: fieldsMap }),
|
|
5629
|
+
),
|
|
5630
|
+
isDone: z.boolean(),
|
|
5631
|
+
continueCursor: z.string().nullable(),
|
|
5632
|
+
returnedCount: z.number(),
|
|
5633
|
+
selectedFields: z.array(z.string()).nullable(),
|
|
5634
|
+
completeness: z.literal("page"),
|
|
5635
|
+
}),
|
|
5496
5636
|
"crm.search": z.array(
|
|
5497
5637
|
z
|
|
5498
5638
|
.object({
|
|
@@ -6217,6 +6357,12 @@ export const convexExtras: Record<string, ConvexExtras> = {
|
|
|
6217
6357
|
// ---------------------------------------------------------------------------
|
|
6218
6358
|
|
|
6219
6359
|
export const requestExamples: Record<string, unknown> = {
|
|
6360
|
+
"email.native.send": {
|
|
6361
|
+
requestId: "send-intro-001",
|
|
6362
|
+
to: [{ email: "ada@example.com", name: "Ada" }],
|
|
6363
|
+
subject: "Introduction",
|
|
6364
|
+
textBody: "Hello Ada",
|
|
6365
|
+
},
|
|
6220
6366
|
"campaigns.accounts.linkedin": {},
|
|
6221
6367
|
"campaigns.create": {
|
|
6222
6368
|
name: "Founder outreach",
|
|
@@ -6470,11 +6616,11 @@ export const requestExamples: Record<string, unknown> = {
|
|
|
6470
6616
|
input_images_base64: ["iVBORw0KGgoAAAANSUhEUg..."],
|
|
6471
6617
|
},
|
|
6472
6618
|
"tool.search": {
|
|
6473
|
-
queries: [{ use_case: "
|
|
6619
|
+
queries: [{ use_case: "list Slack channels" }],
|
|
6474
6620
|
},
|
|
6475
6621
|
"tool.run": {
|
|
6476
|
-
tool_slug: "
|
|
6477
|
-
arguments: {
|
|
6622
|
+
tool_slug: "SLACK_LIST_CHANNELS",
|
|
6623
|
+
arguments: { limit: 10 },
|
|
6478
6624
|
},
|
|
6479
6625
|
"crm.people.search": {
|
|
6480
6626
|
titles: ["Head of Sales"],
|
|
@@ -8019,18 +8165,18 @@ export const responseExamples: Record<string, unknown> = {
|
|
|
8019
8165
|
error: null,
|
|
8020
8166
|
results: [
|
|
8021
8167
|
{
|
|
8022
|
-
use_case: "
|
|
8023
|
-
primary_tool_slugs: ["
|
|
8024
|
-
toolkits: ["
|
|
8168
|
+
use_case: "list Slack channels",
|
|
8169
|
+
primary_tool_slugs: ["SLACK_LIST_CHANNELS"],
|
|
8170
|
+
toolkits: ["slack"],
|
|
8025
8171
|
},
|
|
8026
8172
|
],
|
|
8027
8173
|
toolkit_connection_statuses: [
|
|
8028
|
-
{ toolkit: "
|
|
8174
|
+
{ toolkit: "slack", has_active_connection: true },
|
|
8029
8175
|
],
|
|
8030
8176
|
tool_schemas: {
|
|
8031
|
-
|
|
8032
|
-
toolkit: "
|
|
8033
|
-
tool_slug: "
|
|
8177
|
+
SLACK_LIST_CHANNELS: {
|
|
8178
|
+
toolkit: "slack",
|
|
8179
|
+
tool_slug: "SLACK_LIST_CHANNELS",
|
|
8034
8180
|
execution_ref: "eyJzZXNzaW9uIjoi...",
|
|
8035
8181
|
execution_ref_version: 1,
|
|
8036
8182
|
},
|
|
@@ -8039,11 +8185,11 @@ export const responseExamples: Record<string, unknown> = {
|
|
|
8039
8185
|
execution_ref_version: 1,
|
|
8040
8186
|
},
|
|
8041
8187
|
"tool.run": {
|
|
8042
|
-
data: {
|
|
8188
|
+
data: { channels: [{ id: "C_EXAMPLE", name: "general" }] },
|
|
8043
8189
|
error: null,
|
|
8044
8190
|
log_id: "log_exec_01",
|
|
8045
8191
|
execution_mode: "gateway_tool_router",
|
|
8046
|
-
tool_slug: "
|
|
8192
|
+
tool_slug: "SLACK_LIST_CHANNELS",
|
|
8047
8193
|
tool_router_session_id: "trs_abc123",
|
|
8048
8194
|
},
|
|
8049
8195
|
"tool.disconnect": { id: "ca_github01", deleted: true },
|
|
@@ -53,6 +53,8 @@ export const APP_SDK_SCOPES = [
|
|
|
53
53
|
"cron:schedule",
|
|
54
54
|
"email:read",
|
|
55
55
|
"email:write",
|
|
56
|
+
"environments:read",
|
|
57
|
+
"environments:write",
|
|
56
58
|
"files:read",
|
|
57
59
|
"files:write",
|
|
58
60
|
"http:external",
|
|
@@ -70,6 +72,8 @@ export const APP_SDK_SCOPES = [
|
|
|
70
72
|
"notifications:read",
|
|
71
73
|
"notifications:write",
|
|
72
74
|
"search:read",
|
|
75
|
+
"secrets:read",
|
|
76
|
+
"secrets:write",
|
|
73
77
|
"settings:read",
|
|
74
78
|
"settings:write",
|
|
75
79
|
"store:read",
|
|
@@ -77,12 +81,21 @@ export const APP_SDK_SCOPES = [
|
|
|
77
81
|
"ui",
|
|
78
82
|
"web:read",
|
|
79
83
|
"webhooks:receive",
|
|
80
|
-
"workspace:read"
|
|
84
|
+
"workspace:read",
|
|
85
|
+
"workspace:write"
|
|
81
86
|
] as const;
|
|
82
87
|
export type AppSdkScope = (typeof APP_SDK_SCOPES)[number];
|
|
83
88
|
|
|
84
89
|
/** Every public /api/v1 operation reachable through dench.api.call. */
|
|
85
90
|
export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
|
|
91
|
+
{"id":"environments.list","group":"environments","summary":"List workspace-shared reusable setups and ready revisions (metadata only).","cli":"dench env list","method":"GET","path":"/environments","permission":"environments:read","pathParams":[]},
|
|
92
|
+
{"id":"environments.get","group":"environments","summary":"Inspect a saved setup, its manifest, and an optional immutable revision.","cli":"dench env show","method":"GET","path":"/environments/{name}","permission":"environments:read","pathParams":["name"]},
|
|
93
|
+
{"id":"environments.upload","group":"environments","summary":"Reserve an owner-bound source upload. Prefix the uploaded bytes with the returned proof before saving.","cli":"dench env save","method":"POST","path":"/environments/uploads","permission":"environments:write","pathParams":[]},
|
|
94
|
+
{"id":"environments.save","group":"environments","summary":"Publish an explicitly saved source and manifest for one-time preparation. Returns pending/building until verified; does not run the task.","cli":"dench env save","method":"POST","path":"/environments/{name}","permission":"environments:write","pathParams":["name"]},
|
|
95
|
+
{"id":"environments.delete","group":"environments","summary":"Retire a saved setup from new selection; retain immutable revisions and active job evidence.","cli":"dench env delete","method":"DELETE","path":"/environments/{name}","permission":"environments:write","pathParams":["name"]},
|
|
96
|
+
{"id":"secrets.list","group":"secrets","summary":"List workspace-shared credential names, kinds and versions; never values.","cli":"dench secrets list","method":"GET","path":"/secrets","permission":"secrets:read","pathParams":[]},
|
|
97
|
+
{"id":"secrets.set","group":"secrets","summary":"Encrypt a workspace credential. Use CLI stdin or the secure chat form; return metadata only. Do not put values in chat, manifests or scripts.","cli":"dench secrets set","method":"PUT","path":"/secrets/{name}","permission":"secrets:write","pathParams":["name"]},
|
|
98
|
+
{"id":"secrets.delete","group":"secrets","summary":"Revoke a workspace credential for future resolution, optionally checking its version.","cli":"dench secrets delete","method":"DELETE","path":"/secrets/{name}","permission":"secrets:write","pathParams":["name"]},
|
|
86
99
|
{"id":"campaigns.drafts.create","group":"campaigns","summary":"Create an idempotent empty campaign draft with the caller's available sender pools. Does not launch or send.","cli":"dench campaign draft","method":"POST","path":"/campaigns/drafts","permission":"campaigns:write","pathParams":[]},
|
|
87
100
|
{"id":"campaigns.audience.search","group":"campaigns","summary":"Search people by filters without adding CRM records or campaign recipients. Search credits apply; this is not a free provider preview.","cli":"dench campaign search","method":"POST","path":"/campaigns/audience/search","permission":"campaigns:write","pathParams":[]},
|
|
88
101
|
{"id":"campaigns.people.addFromSearch","group":"campaigns","summary":"Search and add up to 50 people to an existing campaign. New identities become Leads. Search credits apply; use nextPageToken for another page.","cli":"dench campaign add --search","method":"POST","path":"/campaigns/{sequenceId}/people/search","permission":"campaigns:write","pathParams":["sequenceId"]},
|
|
@@ -141,6 +154,7 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
|
|
|
141
154
|
{"id":"chat.send","group":"chat","summary":"Send a message to an existing chat thread.","cli":"dench chat send","method":"POST","path":"/chat/threads/{threadId}/messages","permission":"ai:chat","pathParams":["threadId"]},
|
|
142
155
|
{"id":"chat.follow","group":"chat","summary":"Follow a live chat response stream.","cli":"dench chat follow","method":"GET","path":"/chat/threads/{threadId}/stream","permission":"ai:chat","pathParams":["threadId"]},
|
|
143
156
|
{"id":"crm.objects.list","group":"crm","summary":"List CRM objects.","cli":"dench crm objects list","method":"GET","path":"/crm/objects","permission":"crm:read","pathParams":[]},
|
|
157
|
+
{"id":"crm.objects.listCompact","group":"crm","summary":"List names, display labels, visibility and workspace counts without internal state.","cli":"dench crm objects list --compact","method":"GET","path":"/crm/catalog/objects","permission":"crm:read","pathParams":[]},
|
|
144
158
|
{"id":"crm.objects.get","group":"crm","summary":"Get a CRM object.","cli":"dench crm objects get","method":"GET","path":"/crm/objects/{name}","permission":"crm:read","pathParams":["name"]},
|
|
145
159
|
{"id":"crm.objects.create","group":"crm","summary":"Create a CRM object.","cli":"dench crm objects create","method":"POST","path":"/crm/objects","permission":"crm:write","pathParams":[]},
|
|
146
160
|
{"id":"crm.objects.update","group":"crm","summary":"Update a CRM object.","cli":"dench crm objects update","method":"PATCH","path":"/crm/objects/{name}","permission":"crm:write","pathParams":["name"]},
|
|
@@ -165,6 +179,7 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
|
|
|
165
179
|
{"id":"crm.sidebar.groups.move-item","group":"crm","summary":"Move a sidebar row into a group (groupId set) or back to the top level (groupId null). Open to any member.","cli":"dench crm sidebar group add","method":"POST","path":"/crm/sidebar/groups/move","permission":"crm:write","pathParams":[]},
|
|
166
180
|
{"id":"crm.sidebar.pins.set","group":"crm","summary":"Pin (pinned true) or unpin a Library row — or a whole group — on the home-level Pinned shortcut strip (the \"tab on the left\"). Does not move the row inside Library. Workspace-shared; open to any member.","cli":"dench crm sidebar pin","method":"POST","path":"/crm/sidebar/pins","permission":"crm:write","pathParams":[]},
|
|
167
181
|
{"id":"crm.fields.list","group":"crm","summary":"List fields for a CRM object, including read-only calculation metadata.","cli":"dench crm fields list","method":"GET","path":"/crm/objects/{objectName}/fields","permission":"crm:read","pathParams":["objectName"]},
|
|
182
|
+
{"id":"crm.fields.listCompact","group":"crm","summary":"List field names, types and effective constraints without indexing or enrichment internals.","cli":"dench crm fields list --compact","method":"GET","path":"/crm/catalog/objects/{objectName}/fields","permission":"crm:read","pathParams":["objectName"]},
|
|
168
183
|
{"id":"crm.fields.create","group":"crm","summary":"Create a CRM field or read-only campaign activity boolean column.","cli":"dench crm fields create","method":"POST","path":"/crm/objects/{objectName}/fields","permission":"crm:write","pathParams":["objectName"]},
|
|
169
184
|
{"id":"crm.fields.update","group":"crm","summary":"Update a CRM field or change/explicitly clear an existing campaign calculation.","cli":"dench crm fields update","method":"PATCH","path":"/crm/objects/{objectName}/fields/{fieldName}","permission":"crm:write","pathParams":["objectName","fieldName"]},
|
|
170
185
|
{"id":"crm.fields.delete","group":"crm","summary":"Delete a CRM field.","cli":"dench crm fields delete","method":"DELETE","path":"/crm/objects/{objectName}/fields/{fieldName}","permission":"crm:write","pathParams":["objectName","fieldName"]},
|
|
@@ -237,6 +252,7 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
|
|
|
237
252
|
{"id":"crm.sql","group":"crm","summary":"Run CRM SQL-compatible query.","cli":"dench crm sql","method":"POST","path":"/crm/sql","permission":"crm:read","pathParams":[]},
|
|
238
253
|
{"id":"crm.aggregate","group":"crm","summary":"Aggregate CRM entries.","cli":"dench crm aggregate","method":"POST","path":"/crm/aggregate","permission":"crm:read","pathParams":[]},
|
|
239
254
|
{"id":"crm.search","group":"crm","summary":"Search CRM entries.","cli":"dench crm search","method":"GET","path":"/crm/search","permission":"crm:read","pathParams":[]},
|
|
255
|
+
{"id":"crm.search.page","group":"crm","summary":"Search bounded pages of readable CRM entries, optionally projecting cells. Always follow continueCursor until isDone.","cli":"dench crm search --page","method":"GET","path":"/crm/search/page","permission":"crm:read","pathParams":[]},
|
|
240
256
|
{"id":"crm.statuses.list","group":"crm","summary":"List CRM statuses.","cli":"dench crm statuses list","method":"GET","path":"/crm/objects/{objectName}/statuses","permission":"crm:read","pathParams":["objectName"]},
|
|
241
257
|
{"id":"crm.statuses.set","group":"crm","summary":"Set CRM statuses.","cli":"dench crm statuses set","method":"PUT","path":"/crm/objects/{objectName}/statuses","permission":"crm:write","pathParams":["objectName"]},
|
|
242
258
|
{"id":"crm.batch","group":"crm","summary":"Apply a CRM batch.","cli":"dench crm batch","method":"POST","path":"/crm/batch","permission":"crm:write","pathParams":[]},
|
|
@@ -315,6 +331,9 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
|
|
|
315
331
|
{"id":"email.identity.disable","group":"email","summary":"Soft-disable a sender (or every sender on a domain) for the workspace; sends are blocked until restored.","cli":"dench email identity disable","method":"POST","path":"/email/sending-identities/{identity}/disable","permission":"email:write","pathParams":["identity"]},
|
|
316
332
|
{"id":"email.identity.restore","group":"email","summary":"Restore a previously disabled sender for the workspace.","cli":"dench email identity restore","method":"POST","path":"/email/sending-identities/{identity}/restore","permission":"email:write","pathParams":["identity"]},
|
|
317
333
|
{"id":"email.identity.delete","group":"email","summary":"Permanently delete a sender (or every sender on a domain) from the workspace; re-adding it requires verification from scratch.","cli":"dench email identity delete","method":"DELETE","path":"/email/sending-identities/{identity}","permission":"email:write","pathParams":["identity"]},
|
|
334
|
+
{"id":"email.inbox.search","group":"email","summary":"Search authorized synced mailbox headers with bounded cursor pagination. isDone covers stored records, not provider completeness.","cli":"dench email inbox search","method":"GET","path":"/email/inbox/search","permission":"email:read","pathParams":[]},
|
|
335
|
+
{"id":"email.inbox.thread","group":"email","summary":"Read a bounded page of synced headers using an exact thread handle from inbox search; bodies remain on demand.","cli":"dench email inbox thread","method":"GET","path":"/email/inbox/threads/{threadHandle}","permission":"email:read","pathParams":["threadHandle"]},
|
|
336
|
+
{"id":"email.inbox.message","group":"email","summary":"Read a bounded stored body using an exact message handle from inbox search; rechecks mailbox and record privacy.","cli":"dench email inbox message","method":"GET","path":"/email/inbox/messages/{messageHandle}","permission":"email:read","pathParams":["messageHandle"]},
|
|
318
337
|
{"id":"email.drafts.create","group":"email","summary":"Create an editable Dench email draft and synchronize its selected native mailbox asynchronously. Use a stable requestId for retries.","cli":"dench email draft create","method":"POST","path":"/email/drafts","permission":"email:write","pathParams":[]},
|
|
319
338
|
{"id":"email.drafts.get","group":"email","summary":"Read an email draft, eligible senders and provider sync status.","cli":"dench email draft show","method":"GET","path":"/email/drafts/{draftId}","permission":"email:read","pathParams":["draftId"]},
|
|
320
339
|
{"id":"email.drafts.senders","group":"email","summary":"List native mailboxes this caller may use.","cli":"dench email draft senders","method":"GET","path":"/email/drafts/senders","permission":"email:read","pathParams":[]},
|
|
@@ -322,8 +341,8 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
|
|
|
322
341
|
{"id":"email.drafts.send","group":"email","summary":"Send the current Dench draft revision through its native mailbox. Repeated requests share a durable receipt.","cli":"dench email draft send","method":"POST","path":"/email/drafts/{draftId}/send","permission":"email:write","pathParams":["draftId"]},
|
|
323
342
|
{"id":"email.drafts.upload","group":"email","summary":"Upload attachment bytes authorized against this draft before adding its storage reference.","cli":"dench email draft attach","method":"POST","path":"/email/drafts/{draftId}/attachments","permission":"email:write","pathParams":["draftId"]},
|
|
324
343
|
{"id":"email.drafts.signature","group":"email","summary":"Load the selected mailbox signature for explicit visible insertion.","cli":"dench email draft signature","method":"GET","path":"/email/drafts/{draftId}/signature","permission":"email:read","pathParams":["draftId"]},
|
|
325
|
-
{"id":"email.native.send","group":"email","summary":"Send through a native Gmail or Outlook mailbox with a durable request receipt. Only use for an explicit send request.","cli":"dench email send --mailbox","method":"POST","path":"/email/native/send","permission":"email:write","pathParams":[]},
|
|
326
|
-
{"id":"email.send","group":"email","summary":"Send one raw email (no campaign): to/cc/bcc, custom from-name and reply-to, optional reply threading via replyToMessageId.","cli":"dench email send","method":"POST","path":"/email/send","permission":"email:write","pathParams":[]},
|
|
344
|
+
{"id":"email.native.send","group":"email","summary":"Send through a native Gmail or Outlook mailbox with a durable request receipt. Only use for an explicit send request.","cli":"dench email send [--mailbox <id/email>]","method":"POST","path":"/email/native/send","permission":"email:write","pathParams":[]},
|
|
345
|
+
{"id":"email.send","group":"email","summary":"Send one raw email (no campaign): to/cc/bcc, custom from-name and reply-to, optional reply threading via replyToMessageId.","cli":"dench email send --from <verified-email>","method":"POST","path":"/email/send","permission":"email:write","pathParams":[]},
|
|
327
346
|
{"id":"email.message.get","group":"email","summary":"Read a raw email message's status and open/click counters.","cli":"dench email message status","method":"GET","path":"/email/messages/{messageId}","permission":"email:read","pathParams":["messageId"]},
|
|
328
347
|
{"id":"email.message.list","group":"email","summary":"List recent raw email messages for the workspace.","cli":"dench email message list","method":"GET","path":"/email/messages","permission":"email:read","pathParams":[]},
|
|
329
348
|
{"id":"email.template.create","group":"email","summary":"Create a managed email campaign template.","cli":"dench email template create","method":"POST","path":"/email/templates","permission":"email:write","pathParams":[]},
|
|
@@ -452,23 +471,24 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
|
|
|
452
471
|
{"id":"browser.session.create","group":"browser","summary":"Create a Dench Browser session and return a CDP connect URL for Playwright (chromium.connectOverCDP) plus a live-view URL. Use for durable scripts run from the sandbox.","cli":"dench browser session create","method":"POST","path":"/browser/sessions","permission":"browser:write","pathParams":[]},
|
|
453
472
|
{"id":"browser.session.status","group":"browser","summary":"Get the status, connect URL, and live-view URL for a Dench Browser session.","cli":"dench browser session status","method":"GET","path":"/browser/sessions/{sessionId}","permission":"browser:read","pathParams":["sessionId"]},
|
|
454
473
|
{"id":"browser.session.stop","group":"browser","summary":"Stop a Dench Browser session and release the remote browser.","cli":"dench browser session stop","method":"DELETE","path":"/browser/sessions/{sessionId}","permission":"browser:write","pathParams":["sessionId"]},
|
|
455
|
-
{"id":"agentConfig.identity.show","group":"agent-config","summary":"Read IDENTITY.md.","cli":"dench identity
|
|
456
|
-
{"id":"agentConfig.identity.edit","group":"agent-config","summary":"Update IDENTITY.md.","cli":"dench identity
|
|
457
|
-
{"id":"agentConfig.organisation.show","group":"agent-config","summary":"Read ORGANISATION.md.","cli":"dench organisation
|
|
458
|
-
{"id":"agentConfig.organisation.edit","group":"agent-config","summary":"Update ORGANISATION.md.","cli":"dench organisation
|
|
459
|
-
{"id":"agentConfig.user.show","group":"agent-config","summary":"Read USER.md.","cli":"dench user
|
|
460
|
-
{"id":"agentConfig.user.edit","group":"agent-config","summary":"Update USER.md.","cli":"dench user
|
|
461
|
-
{"id":"agentConfig.tools.show","group":"agent-config","summary":"Read tool notes.","cli":"dench tools
|
|
462
|
-
{"id":"agentConfig.tools.edit","group":"agent-config","summary":"Update tool notes.","cli":"dench tools
|
|
463
|
-
{"id":"
|
|
464
|
-
{"id":"agentConfig.mem.
|
|
465
|
-
{"id":"agentConfig.
|
|
466
|
-
{"id":"agentConfig.bootstrap.
|
|
467
|
-
{"id":"agentConfig.bootstrap.
|
|
474
|
+
{"id":"agentConfig.identity.show","group":"agent-config","summary":"Read IDENTITY.md.","cli":"dench context --sections identity","method":"GET","path":"/agent-config/identity","permission":"agent-config:read","pathParams":[]},
|
|
475
|
+
{"id":"agentConfig.identity.edit","group":"agent-config","summary":"Update IDENTITY.md.","cli":"dench context set identity","method":"PUT","path":"/agent-config/identity","permission":"agent-config:write","pathParams":[]},
|
|
476
|
+
{"id":"agentConfig.organisation.show","group":"agent-config","summary":"Read ORGANISATION.md.","cli":"dench context --sections organisation","method":"GET","path":"/agent-config/organisation","permission":"agent-config:read","pathParams":[]},
|
|
477
|
+
{"id":"agentConfig.organisation.edit","group":"agent-config","summary":"Update ORGANISATION.md.","cli":"dench context set organisation","method":"PUT","path":"/agent-config/organisation","permission":"agent-config:write","pathParams":[]},
|
|
478
|
+
{"id":"agentConfig.user.show","group":"agent-config","summary":"Read USER.md.","cli":"dench context --sections user","method":"GET","path":"/agent-config/user","permission":"agent-config:read","pathParams":[]},
|
|
479
|
+
{"id":"agentConfig.user.edit","group":"agent-config","summary":"Update USER.md.","cli":"dench context set user","method":"PUT","path":"/agent-config/user","permission":"agent-config:write","pathParams":[]},
|
|
480
|
+
{"id":"agentConfig.tools.show","group":"agent-config","summary":"Read tool notes.","cli":"dench context --sections tools","method":"GET","path":"/agent-config/tools","permission":"agent-config:read","pathParams":[]},
|
|
481
|
+
{"id":"agentConfig.tools.edit","group":"agent-config","summary":"Update tool notes.","cli":"dench context set tools","method":"PUT","path":"/agent-config/tools","permission":"agent-config:write","pathParams":[]},
|
|
482
|
+
{"id":"workspace.context.rules.set","group":"workspace","summary":"Update standing workspace rules; credentials belong in secrets and runnable setup in environments.","cli":"dench context set rules","method":"PUT","path":"/context/rules","permission":"workspace:write","pathParams":[]},
|
|
483
|
+
{"id":"agentConfig.mem.show","group":"agent-config","summary":"Read aggregate memory.","cli":"dench mem show","method":"GET","path":"/agent-config/mem","permission":"agent-config:read","deprecated":true,"pathParams":[]},
|
|
484
|
+
{"id":"agentConfig.mem.edit","group":"agent-config","summary":"Update aggregate memory.","cli":"dench mem set","method":"PUT","path":"/agent-config/mem","permission":"agent-config:write","deprecated":true,"pathParams":[]},
|
|
485
|
+
{"id":"agentConfig.bootstrap.show","group":"agent-config","summary":"Read bootstrap state.","cli":"dench bootstrap status","method":"GET","path":"/agent-config/bootstrap","permission":"agent-config:read","deprecated":true,"pathParams":[]},
|
|
486
|
+
{"id":"agentConfig.bootstrap.complete","group":"agent-config","summary":"Complete bootstrap.","cli":"dench bootstrap complete","method":"POST","path":"/agent-config/bootstrap/complete","permission":"agent-config:write","deprecated":true,"pathParams":[]},
|
|
487
|
+
{"id":"agentConfig.bootstrap.template","group":"agent-config","summary":"Update bootstrap template.","cli":"dench bootstrap template","method":"PUT","path":"/agent-config/bootstrap/template","permission":"agent-config:write","deprecated":true,"pathParams":[]},
|
|
468
488
|
{"id":"agentConfig.model.default","group":"agent-config","summary":"Set the default chat model.","cli":"dench model default","method":"PUT","path":"/agent-config/model/default","permission":"agent-config:write","pathParams":[]},
|
|
469
489
|
{"id":"agentConfig.model.thread","group":"agent-config","summary":"Set a thread model override.","cli":"dench model thread","method":"PUT","path":"/agent-config/model/threads/{threadId}","permission":"agent-config:write","pathParams":["threadId"]},
|
|
470
|
-
{"id":"agentConfig.daily.today","group":"agent-config","summary":"Read today's daily activity path.","cli":"dench daily today","method":"GET","path":"/agent-config/daily/today","permission":"agent-config:read","pathParams":[]},
|
|
471
|
-
{"id":"agentConfig.daily.show","group":"agent-config","summary":"Read a daily activity path.","cli":"dench daily show","method":"GET","path":"/agent-config/daily/{date}","permission":"agent-config:read","pathParams":["date"]},
|
|
490
|
+
{"id":"agentConfig.daily.today","group":"agent-config","summary":"Read today's daily activity path.","cli":"dench daily today","method":"GET","path":"/agent-config/daily/today","permission":"agent-config:read","deprecated":true,"pathParams":[]},
|
|
491
|
+
{"id":"agentConfig.daily.show","group":"agent-config","summary":"Read a daily activity path.","cli":"dench daily show","method":"GET","path":"/agent-config/daily/{date}","permission":"agent-config:read","deprecated":true,"pathParams":["date"]},
|
|
472
492
|
{"id":"notifications.list","group":"notifications","summary":"List your notifications (inbox, unread, archived, or all).","cli":"dench notifications list","method":"GET","path":"/notifications","permission":"notifications:read","pathParams":[]},
|
|
473
493
|
{"id":"notifications.unreadCount","group":"notifications","summary":"How many unread notifications you have.","cli":"dench notifications count","method":"GET","path":"/notifications/unread-count","permission":"notifications:read","pathParams":[]},
|
|
474
494
|
{"id":"notifications.read","group":"notifications","summary":"Mark a notification read (or unread).","cli":"dench notifications read","method":"PATCH","path":"/notifications/{notificationId}","permission":"notifications:write","pathParams":["notificationId"]},
|
|
@@ -481,7 +501,7 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
|
|
|
481
501
|
];
|
|
482
502
|
|
|
483
503
|
/** CLI-only operation ids (sessions, fs, imports): never callable from an app. */
|
|
484
|
-
export const APP_SDK_LOCAL_OPERATIONS: readonly string[] = ["sessions.local.list","sessions.local.use","sessions.local.logout","backend.local.configure","enrichment.filters.options","crm.import","crm.export","meetings.import","fs.daemon","apps.validate"];
|
|
504
|
+
export const APP_SDK_LOCAL_OPERATIONS: readonly string[] = ["environments.run","sessions.local.list","sessions.local.use","sessions.local.logout","backend.local.configure","enrichment.filters.options","crm.import","crm.export","meetings.import","fs.daemon","apps.validate"];
|
|
485
505
|
|
|
486
506
|
/** Curated window.dench methods → permission (host + aliases). */
|
|
487
507
|
export const APP_SDK_METHODS: Readonly<Record<string, AppSdkMethodInfo>> = {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import bundle from "./references.generated.json";
|
|
2
|
+
|
|
3
|
+
export const referenceRevision = bundle.revision;
|
|
4
|
+
const files: Record<string, { sha256: string; content: string }> = bundle.files;
|
|
5
|
+
export function getBundledReference(path: string): string | undefined {
|
|
6
|
+
return Object.hasOwn(files, path) ? files[path].content : undefined;
|
|
7
|
+
}
|
|
8
|
+
export function bundledReferenceIndex() {
|
|
9
|
+
return {
|
|
10
|
+
revision: referenceRevision,
|
|
11
|
+
references: Object.entries(files).map(([path, file]) => ({
|
|
12
|
+
path,
|
|
13
|
+
sha256: file.sha256,
|
|
14
|
+
bytes: new TextEncoder().encode(file.content).byteLength,
|
|
15
|
+
})),
|
|
16
|
+
};
|
|
17
|
+
}
|
package/lib/cli-args.ts
CHANGED
|
@@ -27,7 +27,15 @@
|
|
|
27
27
|
* the caller adapts.
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
export class CliArgError extends Error {
|
|
30
|
+
export class CliArgError extends Error {
|
|
31
|
+
readonly code = "invalid_arguments";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Help is a local operation, even after otherwise valid mutation arguments. */
|
|
35
|
+
export function isHelpRequest(args: readonly string[]): boolean {
|
|
36
|
+
if (args.includes("--help") || args.includes("-h")) return true;
|
|
37
|
+
return args[0] === "help" || args[1] === "help";
|
|
38
|
+
}
|
|
31
39
|
|
|
32
40
|
export function shift(args: string[], expected: string): string {
|
|
33
41
|
const value = args.shift();
|
|
@@ -35,10 +43,28 @@ export function shift(args: string[], expected: string): string {
|
|
|
35
43
|
return value;
|
|
36
44
|
}
|
|
37
45
|
|
|
46
|
+
/** A standalone short option cannot supply another flag's value. Descending
|
|
47
|
+
* --sort uses -Field (including single-letter fields); negative numbers remain
|
|
48
|
+
* ordinary values. Longer dash-prefixed text remains supported. */
|
|
49
|
+
export function missingFlagValue(
|
|
50
|
+
value: string | undefined,
|
|
51
|
+
name: string,
|
|
52
|
+
): boolean {
|
|
53
|
+
return (
|
|
54
|
+
value === undefined ||
|
|
55
|
+
value.startsWith("--") ||
|
|
56
|
+
value === "-h" ||
|
|
57
|
+
(name !== "--sort" && /^-[a-zA-Z]$/.test(value))
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
38
61
|
export function getFlag(args: string[], name: string): string | undefined {
|
|
39
62
|
const idx = args.indexOf(name);
|
|
40
63
|
if (idx === -1) return undefined;
|
|
41
64
|
const value = args[idx + 1];
|
|
65
|
+
if (missingFlagValue(value, name)) {
|
|
66
|
+
throw new CliArgError(`${name} needs a value`);
|
|
67
|
+
}
|
|
42
68
|
args.splice(idx, 2);
|
|
43
69
|
return value;
|
|
44
70
|
}
|
|
@@ -141,9 +167,10 @@ export function assertNoUnknownFlags(
|
|
|
141
167
|
// some shells to terminate option parsing) is allowed.
|
|
142
168
|
for (const token of args) {
|
|
143
169
|
if (token === "--") continue;
|
|
144
|
-
if (
|
|
170
|
+
if (/^--?[^\d.]/.test(token)) {
|
|
171
|
+
const path = command.replace(/^dench\s+/, "");
|
|
145
172
|
throw new CliArgError(
|
|
146
|
-
`Unknown flag for ${
|
|
173
|
+
`Unknown flag for ${path}: ${token}. Run \`dench ${path} --help\` for usage.`,
|
|
147
174
|
);
|
|
148
175
|
}
|
|
149
176
|
}
|