@dench.com/cli 3.8.0-staging.389 → 3.8.2-staging.391
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/ads.ts +6 -2
- package/app-sdk.d.ts +132 -27
- package/apps.ts +7 -3
- package/browser.ts +8 -3
- package/campaign.ts +336 -55
- package/chat.ts +8 -6
- package/cron.ts +7 -3
- package/dench.ts +52 -94
- package/image.ts +6 -2
- package/leads.ts +6 -2
- package/lib/api-schemas.ts +186 -20
- package/lib/app-sdk-catalog.generated.ts +3 -3
- package/lib/campaign-steps.ts +474 -12
- package/lib/campaign-timeline.ts +69 -4
- package/lib/command-args.ts +26 -9
- package/lib/command-help.ts +192 -39
- package/lib/command-registry.ts +3 -3
- package/lib/file-command-contract.ts +106 -0
- package/lib/references.generated.json +14 -14
- package/meetings.ts +6 -2
- package/members.ts +6 -2
- package/package.json +1 -1
- package/search.ts +6 -2
- package/tools.ts +9 -5
- package/web.ts +20 -6
package/chat.ts
CHANGED
|
@@ -112,7 +112,11 @@ function out(ctx: ChatCliContext, value: unknown): void {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
function chatHelp(): void {
|
|
115
|
-
console.log(
|
|
115
|
+
console.log(chatHelpText());
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function chatHelpText(): string {
|
|
119
|
+
return `Usage: dench chat <subcommand>
|
|
116
120
|
|
|
117
121
|
List past chat threads (own + shared in this workspace):
|
|
118
122
|
dench chat list [--query <substr>] [--limit N] [--include-archived] [--include-automated] [--json]
|
|
@@ -155,10 +159,8 @@ Spawn a new chat-turn workflow (same agent loop as the web UI):
|
|
|
155
159
|
thread hierarchy from a root thread.
|
|
156
160
|
|
|
157
161
|
Approval policy:
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
--yolo overrides for this single chat turn — every approval gate is
|
|
161
|
-
off, equivalent to flipping the org to YOLO mode for this run.
|
|
162
|
+
Workspace agent runs use Full access by default.
|
|
163
|
+
--yolo remains accepted for compatibility.
|
|
162
164
|
|
|
163
165
|
Auth:
|
|
164
166
|
Inside a sandbox, this just works — DENCH_API_KEY + DENCH_RUN_ID are
|
|
@@ -167,7 +169,7 @@ Auth:
|
|
|
167
169
|
Global flags:
|
|
168
170
|
--json Output raw JSON instead of pretty-printed text.
|
|
169
171
|
--follow After spawning, stream the chat response to stdout.
|
|
170
|
-
|
|
172
|
+
`;
|
|
171
173
|
}
|
|
172
174
|
|
|
173
175
|
export async function runChatCommand(opts: {
|
package/cron.ts
CHANGED
|
@@ -871,7 +871,11 @@ async function runHistory(ctx: CronCliContext): Promise<void> {
|
|
|
871
871
|
// ─── Help ─────────────────────────────────────────────────────────────────
|
|
872
872
|
|
|
873
873
|
function cronHelp(): void {
|
|
874
|
-
console.log(
|
|
874
|
+
console.log(cronHelpText());
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
export function cronHelpText(): string {
|
|
878
|
+
return `Usage: dench cron <subcommand>
|
|
875
879
|
dench routine <subcommand> (alias)
|
|
876
880
|
dench routines <subcommand> (alias)
|
|
877
881
|
|
|
@@ -902,7 +906,7 @@ Create / update:
|
|
|
902
906
|
dench cron create "Inbound lead triage" --prompt "Triage the lead…" --type webhook [--signed]
|
|
903
907
|
|
|
904
908
|
# App-event automation (fires when something happens in a connected app).
|
|
905
|
-
# 1. dench
|
|
909
|
+
# 1. dench integrations --json → connectedAccountId + toolkit
|
|
906
910
|
# 2. dench cron events <toolkit> → event slug
|
|
907
911
|
dench cron create "New GitHub star" --prompt "Thank the new stargazer" \\
|
|
908
912
|
--type app --connection <connectedAccountId> --event <triggerSlug> \\
|
|
@@ -955,7 +959,7 @@ Examples:
|
|
|
955
959
|
Auth: prefers DENCH_API_KEY (sandbox envVar). Falls back to a session token from
|
|
956
960
|
\`dench login\` for local terminals. The Bearer token must carry either
|
|
957
961
|
\`crons:read\` (queries) or \`crons:write\` (mutations) scope, or the wildcard \`*\`.
|
|
958
|
-
|
|
962
|
+
`;
|
|
959
963
|
}
|
|
960
964
|
|
|
961
965
|
// ─── Entry point ──────────────────────────────────────────────────────────
|
package/dench.ts
CHANGED
|
@@ -18,7 +18,6 @@ import { makeFunctionReference } from "convex/server";
|
|
|
18
18
|
import { agentKindLabel, normalizeAgentKind } from "./agentKind";
|
|
19
19
|
import {
|
|
20
20
|
apiHostForDenchHost,
|
|
21
|
-
DEFAULT_HOST,
|
|
22
21
|
isLocalHost,
|
|
23
22
|
LOCAL_HOST,
|
|
24
23
|
normalizeHost,
|
|
@@ -281,6 +280,11 @@ const BOOLEAN_FLAGS = new Set([
|
|
|
281
280
|
]);
|
|
282
281
|
|
|
283
282
|
function positionalArgs() {
|
|
283
|
+
const fileArgs = stripRuntimeFlags(filteredArgs);
|
|
284
|
+
if (fileArgs[0] === "files") {
|
|
285
|
+
const switches = new Set(["--recursive", "-r", "--url"]);
|
|
286
|
+
return fileArgs.filter((value, index) => index < 2 || !switches.has(value));
|
|
287
|
+
}
|
|
284
288
|
const positionals: string[] = [];
|
|
285
289
|
for (let i = 0; i < filteredArgs.length; i++) {
|
|
286
290
|
if (filteredArgs[i].startsWith("--")) {
|
|
@@ -467,8 +471,8 @@ function logHuman(message: string) {
|
|
|
467
471
|
}
|
|
468
472
|
}
|
|
469
473
|
|
|
470
|
-
function
|
|
471
|
-
|
|
474
|
+
function rootUsageText() {
|
|
475
|
+
return `Dench CLI
|
|
472
476
|
|
|
473
477
|
Usage:
|
|
474
478
|
dench signin [--kind <kind>] [--name "AI Agent - Project"] [--no-open] [--json]
|
|
@@ -479,7 +483,9 @@ Usage:
|
|
|
479
483
|
dench sessions [--host <host>] [--json]
|
|
480
484
|
dench use <session-key-or-workspace-slug> [--host <host>] [--json]
|
|
481
485
|
dench logout [session-key-or-workspace-slug] [--session <key-or-scope>] [--host <host>] [--all] [--json]
|
|
482
|
-
dench backend
|
|
486
|
+
dench backend show [--json]
|
|
487
|
+
dench backend set <production|staging|local|url> [--json]
|
|
488
|
+
dench backend clear [--json]
|
|
483
489
|
dench context [--instructions] [--json]
|
|
484
490
|
dench context --sections organisation,user,memory [--json]
|
|
485
491
|
dench instructions [--json]
|
|
@@ -686,62 +692,17 @@ Standing context and memory:
|
|
|
686
692
|
dench context --sections identity,organisation,user,memory,rules,tools [--json]
|
|
687
693
|
dench context set <identity|organisation|user|tools|rules> --stdin
|
|
688
694
|
dench memory search "<query>" | save <key> "<fact>"
|
|
689
|
-
dench model default <id|clear>
|
|
695
|
+
dench model default <id|clear>
|
|
696
|
+
dench model thread <threadId> <id|clear>
|
|
690
697
|
Context describes preferences and instructions. Environments store setup;
|
|
691
698
|
secrets store credentials. A memory note does not install or save either.
|
|
692
699
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
Billing:
|
|
700
|
-
dench billing status shows current AI credits.
|
|
701
|
-
dench billing topup --amount 5 creates a Stripe Checkout link for the human to pay.
|
|
702
|
-
|
|
703
|
-
Agent setup:
|
|
704
|
-
dench signin is the only auth surface. Two transports (browser link
|
|
705
|
-
by default, OTP paste-back with --email <addr>) cover both intents:
|
|
706
|
-
signing in to an existing workspace or creating a new free CRM-only
|
|
707
|
-
workspace (--new-workspace --org-name "<name>"). New workspaces have
|
|
708
|
-
full CRM access; run \`dench upgrade\` to unlock chat, file sync,
|
|
709
|
-
enrichment, and image generation.
|
|
710
|
-
--kind accepts any string. Suggested values: claude_code, codex, cursor,
|
|
711
|
-
hermes, openclaw, or any custom kind (e.g. aider, goose, internal_orchestrator).
|
|
712
|
-
Defaults to "other" when omitted. Values are normalized to lowercase
|
|
713
|
-
snake_case before send (e.g. "Claude Code" -> claude_code).
|
|
714
|
-
After sign-in, run dench context --json and dench crm objects list --json
|
|
715
|
-
to verify the workspace + CRM are wired up. Tasks live as CRM \`task\`
|
|
716
|
-
entries — there is no separate \`dench tasks\` / \`dench task\` /
|
|
717
|
-
\`dench claim\` / \`dench log\` command.
|
|
718
|
-
|
|
719
|
-
Backends and hosts:
|
|
720
|
-
Default backend: ${DEFAULT_HOST} (overridden by \`dench backend set\`)
|
|
721
|
-
Show / change the persistent default:
|
|
722
|
-
dench backend show
|
|
723
|
-
dench backend set production | staging | local | <url>
|
|
724
|
-
dench backend clear
|
|
725
|
-
One-shot overrides for a single command:
|
|
726
|
-
dench --prod <cmd>
|
|
727
|
-
dench --staging <cmd>
|
|
728
|
-
dench --backend local <cmd>
|
|
729
|
-
dench --host https://example.com <cmd>
|
|
730
|
-
DENCH_HOST=https://example.com dench <cmd>
|
|
731
|
-
|
|
732
|
-
Dev fallback (run against a local dev deployment with a dev key):
|
|
733
|
-
DENCH_DEV_AGENT_KEY=... DENCH_WORKSPACE=... dench status --dev
|
|
734
|
-
Inside the dench.com repo, --dev also auto-loads .env / .env.local,
|
|
735
|
-
which carry the dev backend URL and GATEWAY_URL etc. Use --use-dev-env (or
|
|
736
|
-
DENCH_USE_DEV_ENV=1) when you want that auto-load without switching
|
|
737
|
-
the runtime to the dev workspace mode.
|
|
738
|
-
|
|
739
|
-
Advanced:
|
|
740
|
-
For long-lived agents or when the human asks:
|
|
741
|
-
DENCH_SESSION_KEY=stable-agent-id dench signin
|
|
742
|
-
DENCH_SESSION_KEY=stable-agent-id dench logout
|
|
743
|
-
DENCH_SESSION_KEY=stable-agent-id dench status
|
|
744
|
-
`);
|
|
700
|
+
`;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
async function help() {
|
|
704
|
+
const { commandHelp } = await import("./lib/command-help");
|
|
705
|
+
console.log(commandHelp([], rootUsageText()));
|
|
745
706
|
}
|
|
746
707
|
|
|
747
708
|
function contextHelp() {
|
|
@@ -3780,7 +3741,7 @@ async function runFilesCat() {
|
|
|
3780
3741
|
code: "files_cat_not_found",
|
|
3781
3742
|
nextActions: [
|
|
3782
3743
|
"Run `dench files ls` on the parent directory to confirm.",
|
|
3783
|
-
"If the file only
|
|
3744
|
+
"If the file exists only on local disk, upload it with `dench stage <local-path> <workspace-path>`.",
|
|
3784
3745
|
],
|
|
3785
3746
|
});
|
|
3786
3747
|
}
|
|
@@ -3850,11 +3811,11 @@ async function runFilesWrite() {
|
|
|
3850
3811
|
)) as { path: string; contentHash: string };
|
|
3851
3812
|
|
|
3852
3813
|
if (json) {
|
|
3853
|
-
print({ ok: true, ...result, bytes: content
|
|
3814
|
+
print({ ok: true, ...result, bytes: Buffer.byteLength(content, "utf8") });
|
|
3854
3815
|
return;
|
|
3855
3816
|
}
|
|
3856
3817
|
process.stdout.write(
|
|
3857
|
-
`dench files write: ${result.path} (${content
|
|
3818
|
+
`dench files write: ${result.path} (${Buffer.byteLength(content, "utf8")}B)\n`,
|
|
3858
3819
|
);
|
|
3859
3820
|
}
|
|
3860
3821
|
|
|
@@ -3916,7 +3877,7 @@ async function runFilesDownload() {
|
|
|
3916
3877
|
code: "files_download_not_found",
|
|
3917
3878
|
nextActions: [
|
|
3918
3879
|
"Run `dench files ls` on the parent directory to confirm.",
|
|
3919
|
-
"If the file only
|
|
3880
|
+
"If the file exists only on local disk, upload it with `dench stage <local-path> <workspace-path>`.",
|
|
3920
3881
|
],
|
|
3921
3882
|
});
|
|
3922
3883
|
}
|
|
@@ -3990,25 +3951,8 @@ async function runFilesDownload() {
|
|
|
3990
3951
|
async function runFilesCommand() {
|
|
3991
3952
|
const sub = positional(1);
|
|
3992
3953
|
if (!sub || sub === "help" || hasFlag("--help")) {
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
"dench files <ls|cat|write|mv|rm|download> — workspace file ops that update the UI tree",
|
|
3996
|
-
"",
|
|
3997
|
-
" dench files ls [<path>] [--recursive] [--json]",
|
|
3998
|
-
" dench files cat <path> [--json]",
|
|
3999
|
-
" dench files write <path> < file.md (content on stdin)",
|
|
4000
|
-
" dench files mv <src> <dst> [--json]",
|
|
4001
|
-
" dench files rm <path> [--recursive] [--json]",
|
|
4002
|
-
" dench files download <path> [<local-dest>] [--url] [--json]",
|
|
4003
|
-
"",
|
|
4004
|
-
"Paths are POSIX paths under /workspace; you can pass either form.",
|
|
4005
|
-
"These change workspace storage directly (and the daemon syncs to the volume).",
|
|
4006
|
-
"cat prints inline text and is the only way to read the magic files",
|
|
4007
|
-
"(IDENTITY.md, ORGANISATION.md, …), which have no stored bytes.",
|
|
4008
|
-
"download fetches the canonical bytes from workspace storage (dirs recurse);",
|
|
4009
|
-
"--url prints a short-lived signed URL instead of saving.",
|
|
4010
|
-
].join("\n"),
|
|
4011
|
-
);
|
|
3954
|
+
const { commandHelp } = await import("./lib/command-help");
|
|
3955
|
+
process.stdout.write(`${commandHelp(["files"], rootUsageText())}\n`);
|
|
4012
3956
|
return;
|
|
4013
3957
|
}
|
|
4014
3958
|
if (sub === "ls") return await runFilesLs();
|
|
@@ -4328,7 +4272,7 @@ async function main() {
|
|
|
4328
4272
|
);
|
|
4329
4273
|
if (helpArgs[0] === "help") helpArgs.shift();
|
|
4330
4274
|
if (!helpArgs.length) {
|
|
4331
|
-
help();
|
|
4275
|
+
await help();
|
|
4332
4276
|
return;
|
|
4333
4277
|
}
|
|
4334
4278
|
const path = helpArgs.filter(
|
|
@@ -4402,24 +4346,38 @@ async function main() {
|
|
|
4402
4346
|
});
|
|
4403
4347
|
return;
|
|
4404
4348
|
}
|
|
4405
|
-
const { commandHelp } = await import(
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4349
|
+
const { commandHelp, normalizeHelpCommand } = await import(
|
|
4350
|
+
"./lib/command-help"
|
|
4351
|
+
);
|
|
4352
|
+
const family = normalizeHelpCommand(helpArgs)[0];
|
|
4353
|
+
const helpText: Record<string, () => Promise<string>> = {
|
|
4354
|
+
tool: async () => (await import("./tools")).toolHelpText(),
|
|
4355
|
+
email: async () => (await import("./email")).emailHelpText(),
|
|
4356
|
+
crm: async () => (await import("./crm")).crmHelpText(),
|
|
4357
|
+
env: async () => (await import("./environments")).environmentHelpText(),
|
|
4358
|
+
secrets: async () =>
|
|
4359
|
+
(await import("./workspace-secrets")).workspaceSecretsHelpText(),
|
|
4360
|
+
chat: async () => (await import("./chat")).chatHelpText(),
|
|
4361
|
+
cron: async () => (await import("./cron")).cronHelpText(),
|
|
4362
|
+
apps: async () => (await import("./apps")).appsHelpText(),
|
|
4363
|
+
members: async () => (await import("./members")).membersHelpText(),
|
|
4364
|
+
web: async () => (await import("./web")).webHelpText(),
|
|
4365
|
+
meetings: async () => (await import("./meetings")).meetingsHelpText(),
|
|
4366
|
+
lists: async () => (await import("./leads")).listsHelpText(),
|
|
4367
|
+
browser: async () => (await import("./browser")).browserHelpText(),
|
|
4368
|
+
search: async () => (await import("./search")).searchHelpText(),
|
|
4369
|
+
image: async () => (await import("./image")).imageHelpText(),
|
|
4370
|
+
ads: async () => (await import("./ads")).adsHelpText(),
|
|
4371
|
+
campaign: async () => (await import("./campaign")).campaignHelpText(),
|
|
4372
|
+
};
|
|
4373
|
+
const usage = helpText[family] ? await helpText[family]() : rootUsageText();
|
|
4416
4374
|
console.log(commandHelp(helpArgs, usage));
|
|
4417
4375
|
return;
|
|
4418
4376
|
}
|
|
4419
4377
|
const command = positional(0);
|
|
4420
4378
|
const subcommand = positional(1);
|
|
4421
4379
|
|
|
4422
|
-
assertDeclaredCommandFlags(stripRuntimeFlags(
|
|
4380
|
+
assertDeclaredCommandFlags(stripRuntimeFlags(args));
|
|
4423
4381
|
|
|
4424
4382
|
// New setup commands validate before authentication and never consume child flags.
|
|
4425
4383
|
if (command === "env" || command === "secrets") {
|
|
@@ -4555,7 +4513,7 @@ async function main() {
|
|
|
4555
4513
|
}
|
|
4556
4514
|
|
|
4557
4515
|
if (!command || command === "help") {
|
|
4558
|
-
help();
|
|
4516
|
+
await help();
|
|
4559
4517
|
return;
|
|
4560
4518
|
}
|
|
4561
4519
|
|
package/image.ts
CHANGED
|
@@ -384,7 +384,11 @@ async function runEditSubcommand(ctx: ImageCliContext): Promise<void> {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
function imageHelp(): void {
|
|
387
|
-
console.log(
|
|
387
|
+
console.log(imageHelpText());
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export function imageHelpText(): string {
|
|
391
|
+
return `Usage: dench image <subcommand>
|
|
388
392
|
|
|
389
393
|
Generate or edit images via the Dench Cloud Gateway. Auths
|
|
390
394
|
with DENCH_API_KEY or the active \`dench signin\` agent session. Agent
|
|
@@ -415,7 +419,7 @@ Environment variables:
|
|
|
415
419
|
DENCH_ORG_ID Forwarded so wildcard keys can target an org.
|
|
416
420
|
DENCH_RUN_ID Forwarded for telemetry correlation.
|
|
417
421
|
|
|
418
|
-
Exit codes: 0 success, non-zero on gateway / network errors
|
|
422
|
+
Exit codes: 0 success, non-zero on gateway / network errors.`;
|
|
419
423
|
}
|
|
420
424
|
|
|
421
425
|
// ────────────────────────────────────────────────────────────────────────────
|
package/leads.ts
CHANGED
|
@@ -646,7 +646,11 @@ Rename/delete saved searches with \`dench lists rename|delete\`.
|
|
|
646
646
|
}
|
|
647
647
|
|
|
648
648
|
export function listsHelp(): void {
|
|
649
|
-
console.log(
|
|
649
|
+
console.log(listsHelpText());
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
export function listsHelpText(): string {
|
|
653
|
+
return `Dench lists
|
|
650
654
|
|
|
651
655
|
Usage:
|
|
652
656
|
dench lists [--search "September"] [--limit 25] [--cursor <cursor>] [--json]
|
|
@@ -680,7 +684,7 @@ Use \`--preview\` first to review the selection without importing or enrolling a
|
|
|
680
684
|
Delete removes the list, its exported CSV/JSONL files, and any linked watch.
|
|
681
685
|
CRM lists (saved views on Leads/Companies/Job Postings) are managed with
|
|
682
686
|
\`dench crm views list|get|create|rename|delete\`.
|
|
683
|
-
|
|
687
|
+
`;
|
|
684
688
|
}
|
|
685
689
|
|
|
686
690
|
/**
|