@digitalpresence/cliclaw 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/calendar.integration.test.d.ts +2 -0
- package/dist/__tests__/calendar.integration.test.d.ts.map +1 -0
- package/dist/__tests__/calendar.integration.test.js +98 -0
- package/dist/__tests__/calendar.integration.test.js.map +1 -0
- package/dist/__tests__/forms.integration.test.d.ts +2 -0
- package/dist/__tests__/forms.integration.test.d.ts.map +1 -0
- package/dist/__tests__/forms.integration.test.js +243 -0
- package/dist/__tests__/forms.integration.test.js.map +1 -0
- package/dist/__tests__/gdrive.integration.test.d.ts +2 -0
- package/dist/__tests__/gdrive.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gdrive.integration.test.js +186 -0
- package/dist/__tests__/gdrive.integration.test.js.map +1 -0
- package/dist/__tests__/gmail.integration.test.d.ts +2 -0
- package/dist/__tests__/gmail.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gmail.integration.test.js +197 -0
- package/dist/__tests__/gmail.integration.test.js.map +1 -0
- package/dist/__tests__/gslides.integration.test.d.ts +2 -0
- package/dist/__tests__/gslides.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gslides.integration.test.js +124 -0
- package/dist/__tests__/gslides.integration.test.js.map +1 -0
- package/dist/__tests__/sheets.integration.test.d.ts +2 -0
- package/dist/__tests__/sheets.integration.test.d.ts.map +1 -0
- package/dist/__tests__/sheets.integration.test.js +150 -0
- package/dist/__tests__/sheets.integration.test.js.map +1 -0
- package/dist/agent/crud.d.ts +6 -0
- package/dist/agent/crud.d.ts.map +1 -0
- package/dist/agent/crud.js +41 -0
- package/dist/agent/crud.js.map +1 -0
- package/dist/agent/memory.d.ts +14 -0
- package/dist/agent/memory.d.ts.map +1 -0
- package/dist/agent/memory.js +66 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/permissions.d.ts +4 -0
- package/dist/agent/permissions.d.ts.map +1 -0
- package/dist/agent/permissions.js +32 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/calendar/accounts.d.ts +3 -0
- package/dist/calendar/accounts.d.ts.map +1 -0
- package/dist/calendar/accounts.js +21 -0
- package/dist/calendar/accounts.js.map +1 -0
- package/dist/calendar/auth.d.ts +3 -0
- package/dist/calendar/auth.d.ts.map +1 -0
- package/dist/calendar/auth.js +41 -0
- package/dist/calendar/auth.js.map +1 -0
- package/dist/calendar/calendars.d.ts +3 -0
- package/dist/calendar/calendars.d.ts.map +1 -0
- package/dist/calendar/calendars.js +28 -0
- package/dist/calendar/calendars.js.map +1 -0
- package/dist/calendar/create.d.ts +3 -0
- package/dist/calendar/create.d.ts.map +1 -0
- package/dist/calendar/create.js +31 -0
- package/dist/calendar/create.js.map +1 -0
- package/dist/calendar/delete.d.ts +3 -0
- package/dist/calendar/delete.d.ts.map +1 -0
- package/dist/calendar/delete.js +21 -0
- package/dist/calendar/delete.js.map +1 -0
- package/dist/calendar/events.d.ts +3 -0
- package/dist/calendar/events.d.ts.map +1 -0
- package/dist/calendar/events.js +37 -0
- package/dist/calendar/events.js.map +1 -0
- package/dist/calendar/get.d.ts +3 -0
- package/dist/calendar/get.d.ts.map +1 -0
- package/dist/calendar/get.js +21 -0
- package/dist/calendar/get.js.map +1 -0
- package/dist/calendar/update.d.ts +3 -0
- package/dist/calendar/update.d.ts.map +1 -0
- package/dist/calendar/update.js +31 -0
- package/dist/calendar/update.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +37 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agent.d.ts +6 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +107 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/calendar.d.ts +9 -0
- package/dist/commands/calendar.d.ts.map +1 -0
- package/dist/commands/calendar.js +104 -0
- package/dist/commands/calendar.js.map +1 -0
- package/dist/commands/cron.d.ts +6 -0
- package/dist/commands/cron.d.ts.map +1 -0
- package/dist/commands/cron.js +103 -0
- package/dist/commands/cron.js.map +1 -0
- package/dist/commands/forms.d.ts +9 -0
- package/dist/commands/forms.d.ts.map +1 -0
- package/dist/commands/forms.js +139 -0
- package/dist/commands/forms.js.map +1 -0
- package/dist/commands/gdrive.d.ts +9 -0
- package/dist/commands/gdrive.d.ts.map +1 -0
- package/dist/commands/gdrive.js +198 -0
- package/dist/commands/gdrive.js.map +1 -0
- package/dist/commands/gmail.d.ts +9 -0
- package/dist/commands/gmail.d.ts.map +1 -0
- package/dist/commands/gmail.js +231 -0
- package/dist/commands/gmail.js.map +1 -0
- package/dist/commands/gslides.d.ts +9 -0
- package/dist/commands/gslides.d.ts.map +1 -0
- package/dist/commands/gslides.js +167 -0
- package/dist/commands/gslides.js.map +1 -0
- package/dist/commands/sheets.d.ts +9 -0
- package/dist/commands/sheets.d.ts.map +1 -0
- package/dist/commands/sheets.js +174 -0
- package/dist/commands/sheets.js.map +1 -0
- package/dist/cron/daemon.d.ts +3 -0
- package/dist/cron/daemon.d.ts.map +1 -0
- package/dist/cron/daemon.js +127 -0
- package/dist/cron/daemon.js.map +1 -0
- package/dist/cron/handlers.d.ts +6 -0
- package/dist/cron/handlers.d.ts.map +1 -0
- package/dist/cron/handlers.js +58 -0
- package/dist/cron/handlers.js.map +1 -0
- package/dist/cron/logger.d.ts +4 -0
- package/dist/cron/logger.d.ts.map +1 -0
- package/dist/cron/logger.js +11 -0
- package/dist/cron/logger.js.map +1 -0
- package/dist/cron/progress.d.ts +25 -0
- package/dist/cron/progress.d.ts.map +1 -0
- package/dist/cron/progress.js +71 -0
- package/dist/cron/progress.js.map +1 -0
- package/dist/cron/ralph-wiggum.d.ts +18 -0
- package/dist/cron/ralph-wiggum.d.ts.map +1 -0
- package/dist/cron/ralph-wiggum.js +143 -0
- package/dist/cron/ralph-wiggum.js.map +1 -0
- package/dist/forms/accounts.d.ts +3 -0
- package/dist/forms/accounts.d.ts.map +1 -0
- package/dist/forms/accounts.js +20 -0
- package/dist/forms/accounts.js.map +1 -0
- package/dist/forms/auth.d.ts +3 -0
- package/dist/forms/auth.d.ts.map +1 -0
- package/dist/forms/auth.js +41 -0
- package/dist/forms/auth.js.map +1 -0
- package/dist/forms/create.d.ts +3 -0
- package/dist/forms/create.d.ts.map +1 -0
- package/dist/forms/create.js +28 -0
- package/dist/forms/create.js.map +1 -0
- package/dist/forms/get.d.ts +3 -0
- package/dist/forms/get.d.ts.map +1 -0
- package/dist/forms/get.js +21 -0
- package/dist/forms/get.js.map +1 -0
- package/dist/forms/list.d.ts +3 -0
- package/dist/forms/list.d.ts.map +1 -0
- package/dist/forms/list.js +33 -0
- package/dist/forms/list.js.map +1 -0
- package/dist/forms/questions.d.ts +6 -0
- package/dist/forms/questions.d.ts.map +1 -0
- package/dist/forms/questions.js +179 -0
- package/dist/forms/questions.js.map +1 -0
- package/dist/forms/responses.d.ts +4 -0
- package/dist/forms/responses.d.ts.map +1 -0
- package/dist/forms/responses.js +40 -0
- package/dist/forms/responses.js.map +1 -0
- package/dist/forms/update.d.ts +3 -0
- package/dist/forms/update.d.ts.map +1 -0
- package/dist/forms/update.js +44 -0
- package/dist/forms/update.js.map +1 -0
- package/dist/gdrive/about.d.ts +3 -0
- package/dist/gdrive/about.d.ts.map +1 -0
- package/dist/gdrive/about.js +31 -0
- package/dist/gdrive/about.js.map +1 -0
- package/dist/gdrive/accounts.d.ts +3 -0
- package/dist/gdrive/accounts.d.ts.map +1 -0
- package/dist/gdrive/accounts.js +20 -0
- package/dist/gdrive/accounts.js.map +1 -0
- package/dist/gdrive/auth.d.ts +3 -0
- package/dist/gdrive/auth.d.ts.map +1 -0
- package/dist/gdrive/auth.js +51 -0
- package/dist/gdrive/auth.js.map +1 -0
- package/dist/gdrive/files.d.ts +12 -0
- package/dist/gdrive/files.d.ts.map +1 -0
- package/dist/gdrive/files.js +174 -0
- package/dist/gdrive/files.js.map +1 -0
- package/dist/gdrive/folders.d.ts +4 -0
- package/dist/gdrive/folders.d.ts.map +1 -0
- package/dist/gdrive/folders.js +46 -0
- package/dist/gdrive/folders.js.map +1 -0
- package/dist/gdrive/search.d.ts +3 -0
- package/dist/gdrive/search.d.ts.map +1 -0
- package/dist/gdrive/search.js +23 -0
- package/dist/gdrive/search.js.map +1 -0
- package/dist/gdrive/sharing.d.ts +5 -0
- package/dist/gdrive/sharing.d.ts.map +1 -0
- package/dist/gdrive/sharing.js +54 -0
- package/dist/gdrive/sharing.js.map +1 -0
- package/dist/gmail/accounts.d.ts +3 -0
- package/dist/gmail/accounts.d.ts.map +1 -0
- package/dist/gmail/accounts.js +18 -0
- package/dist/gmail/accounts.js.map +1 -0
- package/dist/gmail/auth.d.ts +3 -0
- package/dist/gmail/auth.d.ts.map +1 -0
- package/dist/gmail/auth.js +50 -0
- package/dist/gmail/auth.js.map +1 -0
- package/dist/gmail/drafts.d.ts +7 -0
- package/dist/gmail/drafts.d.ts.map +1 -0
- package/dist/gmail/drafts.js +103 -0
- package/dist/gmail/drafts.js.map +1 -0
- package/dist/gmail/get.d.ts +4 -0
- package/dist/gmail/get.d.ts.map +1 -0
- package/dist/gmail/get.js +140 -0
- package/dist/gmail/get.js.map +1 -0
- package/dist/gmail/inbox.d.ts +4 -0
- package/dist/gmail/inbox.d.ts.map +1 -0
- package/dist/gmail/inbox.js +45 -0
- package/dist/gmail/inbox.js.map +1 -0
- package/dist/gmail/labels.d.ts +5 -0
- package/dist/gmail/labels.d.ts.map +1 -0
- package/dist/gmail/labels.js +45 -0
- package/dist/gmail/labels.js.map +1 -0
- package/dist/gmail/modify.d.ts +5 -0
- package/dist/gmail/modify.d.ts.map +1 -0
- package/dist/gmail/modify.js +68 -0
- package/dist/gmail/modify.js.map +1 -0
- package/dist/gmail/send.d.ts +5 -0
- package/dist/gmail/send.d.ts.map +1 -0
- package/dist/gmail/send.js +310 -0
- package/dist/gmail/send.js.map +1 -0
- package/dist/gmail/threads.d.ts +4 -0
- package/dist/gmail/threads.d.ts.map +1 -0
- package/dist/gmail/threads.js +47 -0
- package/dist/gmail/threads.js.map +1 -0
- package/dist/gslides/accounts.d.ts +3 -0
- package/dist/gslides/accounts.d.ts.map +1 -0
- package/dist/gslides/accounts.js +20 -0
- package/dist/gslides/accounts.js.map +1 -0
- package/dist/gslides/auth.d.ts +3 -0
- package/dist/gslides/auth.d.ts.map +1 -0
- package/dist/gslides/auth.js +50 -0
- package/dist/gslides/auth.js.map +1 -0
- package/dist/gslides/presentations.d.ts +29 -0
- package/dist/gslides/presentations.d.ts.map +1 -0
- package/dist/gslides/presentations.js +320 -0
- package/dist/gslides/presentations.js.map +1 -0
- package/dist/lib/config.d.ts +6 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +12 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/media-utils.d.ts +5 -0
- package/dist/lib/media-utils.d.ts.map +1 -0
- package/dist/lib/media-utils.js +79 -0
- package/dist/lib/media-utils.js.map +1 -0
- package/dist/lib/output.d.ts +4 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +12 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/sheets/accounts.d.ts +3 -0
- package/dist/sheets/accounts.d.ts.map +1 -0
- package/dist/sheets/accounts.js +20 -0
- package/dist/sheets/accounts.js.map +1 -0
- package/dist/sheets/auth.d.ts +3 -0
- package/dist/sheets/auth.d.ts.map +1 -0
- package/dist/sheets/auth.js +56 -0
- package/dist/sheets/auth.js.map +1 -0
- package/dist/sheets/cells.d.ts +6 -0
- package/dist/sheets/cells.d.ts.map +1 -0
- package/dist/sheets/cells.js +89 -0
- package/dist/sheets/cells.js.map +1 -0
- package/dist/sheets/format.d.ts +8 -0
- package/dist/sheets/format.d.ts.map +1 -0
- package/dist/sheets/format.js +97 -0
- package/dist/sheets/format.js.map +1 -0
- package/dist/sheets/sheets-tab.d.ts +6 -0
- package/dist/sheets/sheets-tab.d.ts.map +1 -0
- package/dist/sheets/sheets-tab.js +88 -0
- package/dist/sheets/sheets-tab.js.map +1 -0
- package/dist/sheets/spreadsheets.d.ts +6 -0
- package/dist/sheets/spreadsheets.d.ts.map +1 -0
- package/dist/sheets/spreadsheets.js +88 -0
- package/dist/sheets/spreadsheets.js.map +1 -0
- package/package.json +33 -0
- package/src/__tests__/calendar.integration.test.ts +152 -0
- package/src/__tests__/forms.integration.test.ts +403 -0
- package/src/__tests__/gdrive.integration.test.ts +253 -0
- package/src/__tests__/gmail.integration.test.ts +294 -0
- package/src/__tests__/gslides.integration.test.ts +195 -0
- package/src/__tests__/sheets.integration.test.ts +234 -0
- package/src/agent/crud.ts +54 -0
- package/src/agent/memory.ts +95 -0
- package/src/agent/permissions.ts +54 -0
- package/src/calendar/accounts.ts +25 -0
- package/src/calendar/auth.ts +45 -0
- package/src/calendar/calendars.ts +32 -0
- package/src/calendar/create.ts +44 -0
- package/src/calendar/delete.ts +27 -0
- package/src/calendar/events.ts +45 -0
- package/src/calendar/get.ts +27 -0
- package/src/calendar/update.ts +44 -0
- package/src/cli.ts +41 -0
- package/src/commands/agent.ts +128 -0
- package/src/commands/calendar.ts +127 -0
- package/src/commands/cron.ts +126 -0
- package/src/commands/forms.ts +158 -0
- package/src/commands/gdrive.ts +225 -0
- package/src/commands/gmail.ts +290 -0
- package/src/commands/gslides.ts +188 -0
- package/src/commands/sheets.ts +193 -0
- package/src/cron/daemon.ts +143 -0
- package/src/cron/handlers.ts +78 -0
- package/src/cron/logger.ts +20 -0
- package/src/cron/progress.ts +90 -0
- package/src/cron/ralph-wiggum.ts +172 -0
- package/src/forms/accounts.ts +24 -0
- package/src/forms/auth.ts +45 -0
- package/src/forms/create.ts +34 -0
- package/src/forms/get.ts +26 -0
- package/src/forms/list.ts +38 -0
- package/src/forms/questions.ts +209 -0
- package/src/forms/responses.ts +50 -0
- package/src/forms/update.ts +57 -0
- package/src/gdrive/about.ts +36 -0
- package/src/gdrive/accounts.ts +24 -0
- package/src/gdrive/auth.ts +55 -0
- package/src/gdrive/files.ts +237 -0
- package/src/gdrive/folders.ts +58 -0
- package/src/gdrive/search.ts +30 -0
- package/src/gdrive/sharing.ts +72 -0
- package/src/gmail/accounts.ts +22 -0
- package/src/gmail/auth.ts +53 -0
- package/src/gmail/drafts.ts +166 -0
- package/src/gmail/get.ts +195 -0
- package/src/gmail/inbox.ts +78 -0
- package/src/gmail/labels.ts +69 -0
- package/src/gmail/modify.ts +89 -0
- package/src/gmail/send.ts +424 -0
- package/src/gmail/threads.ts +68 -0
- package/src/gslides/accounts.ts +24 -0
- package/src/gslides/auth.ts +54 -0
- package/src/gslides/presentations.ts +384 -0
- package/src/lib/config.ts +14 -0
- package/src/lib/media-utils.ts +82 -0
- package/src/lib/output.ts +13 -0
- package/src/sheets/accounts.ts +24 -0
- package/src/sheets/auth.ts +60 -0
- package/src/sheets/cells.ts +112 -0
- package/src/sheets/format.ts +114 -0
- package/src/sheets/sheets-tab.ts +109 -0
- package/src/sheets/spreadsheets.ts +106 -0
- package/tsconfig.json +8 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { OAuthClientManager } from "@digitalpresence/cliclaw-auth";
|
|
3
|
+
import { handleAuth } from "../forms/auth.js";
|
|
4
|
+
import { handleAccounts } from "../forms/accounts.js";
|
|
5
|
+
import { handleList } from "../forms/list.js";
|
|
6
|
+
import { handleGetForm } from "../forms/get.js";
|
|
7
|
+
import { handleCreateForm } from "../forms/create.js";
|
|
8
|
+
import { handleUpdateForm } from "../forms/update.js";
|
|
9
|
+
import { handleQuestions, handleAddQuestion, handleUpdateQuestion, handleDeleteQuestion } from "../forms/questions.js";
|
|
10
|
+
import { handleResponses, handleGetResponse } from "../forms/responses.js";
|
|
11
|
+
|
|
12
|
+
type ClientFactory = () => { clientManager: OAuthClientManager; port: number };
|
|
13
|
+
|
|
14
|
+
export function registerFormsCommands(program: Command, getClient: ClientFactory): void {
|
|
15
|
+
let cached: { clientManager: OAuthClientManager; port: number } | null = null;
|
|
16
|
+
function resolve() {
|
|
17
|
+
if (!cached) cached = getClient();
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const forms = program.command("forms").description("Google Forms commands");
|
|
22
|
+
|
|
23
|
+
forms
|
|
24
|
+
.command("auth")
|
|
25
|
+
.description("Authenticate with Google Forms via Google OAuth2")
|
|
26
|
+
.option("--account <name>", "Account name", "default")
|
|
27
|
+
.action(async (opts) => {
|
|
28
|
+
const { clientManager, port } = resolve();
|
|
29
|
+
await handleAuth(clientManager, port, opts.account);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
forms
|
|
33
|
+
.command("accounts")
|
|
34
|
+
.description("List authenticated Google Forms accounts")
|
|
35
|
+
.action(async () => {
|
|
36
|
+
const { clientManager } = resolve();
|
|
37
|
+
await handleAccounts(clientManager);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
forms
|
|
41
|
+
.command("list")
|
|
42
|
+
.description("List all forms")
|
|
43
|
+
.option("--max-results <n>", "Maximum forms to return", "20")
|
|
44
|
+
.option("--account <name>", "Account name", "default")
|
|
45
|
+
.action(async (opts) => {
|
|
46
|
+
const { clientManager } = resolve();
|
|
47
|
+
await handleList(clientManager, opts.account, parseInt(opts.maxResults));
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
forms
|
|
51
|
+
.command("get")
|
|
52
|
+
.description("Get form details by ID")
|
|
53
|
+
.requiredOption("--form-id <id>", "Form ID")
|
|
54
|
+
.option("--account <name>", "Account name", "default")
|
|
55
|
+
.action(async (opts) => {
|
|
56
|
+
const { clientManager } = resolve();
|
|
57
|
+
await handleGetForm(clientManager, opts.account, opts.formId);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
forms
|
|
61
|
+
.command("create")
|
|
62
|
+
.description("Create a new form")
|
|
63
|
+
.requiredOption("--title <text>", "Form title")
|
|
64
|
+
.option("--document-title <text>", "Document title (defaults to form title)")
|
|
65
|
+
.option("--account <name>", "Account name", "default")
|
|
66
|
+
.action(async (opts) => {
|
|
67
|
+
const { clientManager } = resolve();
|
|
68
|
+
await handleCreateForm(clientManager, opts.account, opts.title, opts.documentTitle);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
forms
|
|
72
|
+
.command("update")
|
|
73
|
+
.description("Update form metadata")
|
|
74
|
+
.requiredOption("--form-id <id>", "Form ID")
|
|
75
|
+
.option("--title <text>", "New form title")
|
|
76
|
+
.option("--description <text>", "New form description")
|
|
77
|
+
.option("--account <name>", "Account name", "default")
|
|
78
|
+
.action(async (opts) => {
|
|
79
|
+
const { clientManager } = resolve();
|
|
80
|
+
await handleUpdateForm(clientManager, opts.account, opts.formId, opts.title, opts.description);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
forms
|
|
84
|
+
.command("questions")
|
|
85
|
+
.description("List questions in a form")
|
|
86
|
+
.requiredOption("--form-id <id>", "Form ID")
|
|
87
|
+
.option("--account <name>", "Account name", "default")
|
|
88
|
+
.action(async (opts) => {
|
|
89
|
+
const { clientManager } = resolve();
|
|
90
|
+
await handleQuestions(clientManager, opts.account, opts.formId);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
forms
|
|
94
|
+
.command("add-question")
|
|
95
|
+
.description("Add a question to a form")
|
|
96
|
+
.requiredOption("--form-id <id>", "Form ID")
|
|
97
|
+
.requiredOption("--title <text>", "Question title")
|
|
98
|
+
.option("--type <type>", "Question type: text, paragraph, choice, checkbox, dropdown, scale, date, time", "text")
|
|
99
|
+
.option("--required", "Make question required", false)
|
|
100
|
+
.option("--options <items>", "Comma-separated options (for choice, checkbox, dropdown)")
|
|
101
|
+
.option("--index <n>", "Position index (0-based)")
|
|
102
|
+
.option("--account <name>", "Account name", "default")
|
|
103
|
+
.action(async (opts) => {
|
|
104
|
+
const { clientManager } = resolve();
|
|
105
|
+
const options = opts.options ? opts.options.split(",").map((o: string) => o.trim()) : undefined;
|
|
106
|
+
const index = opts.index !== undefined ? parseInt(opts.index) : undefined;
|
|
107
|
+
await handleAddQuestion(clientManager, opts.account, opts.formId, opts.title, opts.type, opts.required, options, index);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
forms
|
|
111
|
+
.command("update-question")
|
|
112
|
+
.description("Update a question in a form")
|
|
113
|
+
.requiredOption("--form-id <id>", "Form ID")
|
|
114
|
+
.requiredOption("--item-index <n>", "Item index (0-based)")
|
|
115
|
+
.option("--title <text>", "New question title")
|
|
116
|
+
.option("--required", "Make question required")
|
|
117
|
+
.option("--no-required", "Make question optional")
|
|
118
|
+
.option("--account <name>", "Account name", "default")
|
|
119
|
+
.action(async (opts) => {
|
|
120
|
+
const { clientManager } = resolve();
|
|
121
|
+
await handleUpdateQuestion(
|
|
122
|
+
clientManager, opts.account, opts.formId,
|
|
123
|
+
parseInt(opts.itemIndex), opts.title, opts.required,
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
forms
|
|
128
|
+
.command("delete-question")
|
|
129
|
+
.description("Delete a question from a form")
|
|
130
|
+
.requiredOption("--form-id <id>", "Form ID")
|
|
131
|
+
.requiredOption("--item-index <n>", "Item index (0-based)")
|
|
132
|
+
.option("--account <name>", "Account name", "default")
|
|
133
|
+
.action(async (opts) => {
|
|
134
|
+
const { clientManager } = resolve();
|
|
135
|
+
await handleDeleteQuestion(clientManager, opts.account, opts.formId, parseInt(opts.itemIndex));
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
forms
|
|
139
|
+
.command("responses")
|
|
140
|
+
.description("List all responses for a form")
|
|
141
|
+
.requiredOption("--form-id <id>", "Form ID")
|
|
142
|
+
.option("--account <name>", "Account name", "default")
|
|
143
|
+
.action(async (opts) => {
|
|
144
|
+
const { clientManager } = resolve();
|
|
145
|
+
await handleResponses(clientManager, opts.account, opts.formId);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
forms
|
|
149
|
+
.command("response")
|
|
150
|
+
.description("Get a single response by ID")
|
|
151
|
+
.requiredOption("--form-id <id>", "Form ID")
|
|
152
|
+
.requiredOption("--response-id <id>", "Response ID")
|
|
153
|
+
.option("--account <name>", "Account name", "default")
|
|
154
|
+
.action(async (opts) => {
|
|
155
|
+
const { clientManager } = resolve();
|
|
156
|
+
await handleGetResponse(clientManager, opts.account, opts.formId, opts.responseId);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { OAuthClientManager } from "@digitalpresence/cliclaw-auth";
|
|
3
|
+
import { handleAuth } from "../gdrive/auth.js";
|
|
4
|
+
import { handleAccounts } from "../gdrive/accounts.js";
|
|
5
|
+
import {
|
|
6
|
+
handleList, handleGet, handleDownload, handleUpload,
|
|
7
|
+
handleDelete, handleTrash, handleUntrash,
|
|
8
|
+
handleMove, handleCopy, handleRename,
|
|
9
|
+
} from "../gdrive/files.js";
|
|
10
|
+
import { handleMkdir, handleListFolder } from "../gdrive/folders.js";
|
|
11
|
+
import { handleSearch } from "../gdrive/search.js";
|
|
12
|
+
import { handleShare, handleUnshare, handlePermissions } from "../gdrive/sharing.js";
|
|
13
|
+
import { handleAbout } from "../gdrive/about.js";
|
|
14
|
+
|
|
15
|
+
type ClientFactory = () => { clientManager: OAuthClientManager; port: number };
|
|
16
|
+
|
|
17
|
+
export function registerGDriveCommands(program: Command, getClient: ClientFactory): void {
|
|
18
|
+
let cached: { clientManager: OAuthClientManager; port: number } | null = null;
|
|
19
|
+
function resolve() {
|
|
20
|
+
if (!cached) cached = getClient();
|
|
21
|
+
return cached;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const gdrive = program.command("gdrive").description("Google Drive commands");
|
|
25
|
+
|
|
26
|
+
gdrive
|
|
27
|
+
.command("auth")
|
|
28
|
+
.description("Authenticate with Google Drive via Google OAuth2")
|
|
29
|
+
.option("--account <name>", "Account name", "default")
|
|
30
|
+
.action(async (opts) => {
|
|
31
|
+
const { clientManager, port } = resolve();
|
|
32
|
+
await handleAuth(clientManager, port, opts.account);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
gdrive
|
|
36
|
+
.command("accounts")
|
|
37
|
+
.description("List authenticated Google Drive accounts")
|
|
38
|
+
.action(async () => {
|
|
39
|
+
const { clientManager } = resolve();
|
|
40
|
+
await handleAccounts(clientManager);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
gdrive
|
|
44
|
+
.command("list")
|
|
45
|
+
.description("List files in Google Drive")
|
|
46
|
+
.option("--max-results <n>", "Maximum files to return", "20")
|
|
47
|
+
.option("--query <query>", "Drive query filter (e.g. mimeType='application/pdf')")
|
|
48
|
+
.option("--account <name>", "Account name", "default")
|
|
49
|
+
.action(async (opts) => {
|
|
50
|
+
const { clientManager } = resolve();
|
|
51
|
+
await handleList(clientManager, opts.account, parseInt(opts.maxResults), opts.query);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
gdrive
|
|
55
|
+
.command("get")
|
|
56
|
+
.description("Get file metadata by ID")
|
|
57
|
+
.requiredOption("--id <id>", "File ID")
|
|
58
|
+
.option("--account <name>", "Account name", "default")
|
|
59
|
+
.action(async (opts) => {
|
|
60
|
+
const { clientManager } = resolve();
|
|
61
|
+
await handleGet(clientManager, opts.account, opts.id);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
gdrive
|
|
65
|
+
.command("download")
|
|
66
|
+
.description("Download a file")
|
|
67
|
+
.requiredOption("--id <id>", "File ID")
|
|
68
|
+
.requiredOption("--save-dir <dir>", "Directory to save to")
|
|
69
|
+
.option("--filename <name>", "Override filename")
|
|
70
|
+
.option("--account <name>", "Account name", "default")
|
|
71
|
+
.action(async (opts) => {
|
|
72
|
+
const { clientManager } = resolve();
|
|
73
|
+
await handleDownload(clientManager, opts.account, opts.id, opts.saveDir, opts.filename);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
gdrive
|
|
77
|
+
.command("upload")
|
|
78
|
+
.description("Upload a file")
|
|
79
|
+
.requiredOption("--file <path>", "Local file path")
|
|
80
|
+
.option("--name <name>", "Override filename in Drive")
|
|
81
|
+
.option("--parent <id>", "Parent folder ID")
|
|
82
|
+
.option("--account <name>", "Account name", "default")
|
|
83
|
+
.action(async (opts) => {
|
|
84
|
+
const { clientManager } = resolve();
|
|
85
|
+
await handleUpload(clientManager, opts.account, opts.file, opts.name, opts.parent);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
gdrive
|
|
89
|
+
.command("delete")
|
|
90
|
+
.description("Permanently delete a file")
|
|
91
|
+
.requiredOption("--id <id>", "File ID")
|
|
92
|
+
.option("--account <name>", "Account name", "default")
|
|
93
|
+
.action(async (opts) => {
|
|
94
|
+
const { clientManager } = resolve();
|
|
95
|
+
await handleDelete(clientManager, opts.account, opts.id);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
gdrive
|
|
99
|
+
.command("trash")
|
|
100
|
+
.description("Move a file to trash")
|
|
101
|
+
.requiredOption("--id <id>", "File ID")
|
|
102
|
+
.option("--account <name>", "Account name", "default")
|
|
103
|
+
.action(async (opts) => {
|
|
104
|
+
const { clientManager } = resolve();
|
|
105
|
+
await handleTrash(clientManager, opts.account, opts.id);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
gdrive
|
|
109
|
+
.command("untrash")
|
|
110
|
+
.description("Restore a file from trash")
|
|
111
|
+
.requiredOption("--id <id>", "File ID")
|
|
112
|
+
.option("--account <name>", "Account name", "default")
|
|
113
|
+
.action(async (opts) => {
|
|
114
|
+
const { clientManager } = resolve();
|
|
115
|
+
await handleUntrash(clientManager, opts.account, opts.id);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
gdrive
|
|
119
|
+
.command("move")
|
|
120
|
+
.description("Move a file to a different folder")
|
|
121
|
+
.requiredOption("--id <id>", "File ID")
|
|
122
|
+
.requiredOption("--to <folder-id>", "Destination folder ID")
|
|
123
|
+
.option("--account <name>", "Account name", "default")
|
|
124
|
+
.action(async (opts) => {
|
|
125
|
+
const { clientManager } = resolve();
|
|
126
|
+
await handleMove(clientManager, opts.account, opts.id, opts.to);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
gdrive
|
|
130
|
+
.command("copy")
|
|
131
|
+
.description("Copy a file")
|
|
132
|
+
.requiredOption("--id <id>", "File ID")
|
|
133
|
+
.option("--name <name>", "Name for the copy")
|
|
134
|
+
.option("--account <name>", "Account name", "default")
|
|
135
|
+
.action(async (opts) => {
|
|
136
|
+
const { clientManager } = resolve();
|
|
137
|
+
await handleCopy(clientManager, opts.account, opts.id, opts.name);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
gdrive
|
|
141
|
+
.command("rename")
|
|
142
|
+
.description("Rename a file")
|
|
143
|
+
.requiredOption("--id <id>", "File ID")
|
|
144
|
+
.requiredOption("--name <name>", "New name")
|
|
145
|
+
.option("--account <name>", "Account name", "default")
|
|
146
|
+
.action(async (opts) => {
|
|
147
|
+
const { clientManager } = resolve();
|
|
148
|
+
await handleRename(clientManager, opts.account, opts.id, opts.name);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
gdrive
|
|
152
|
+
.command("mkdir")
|
|
153
|
+
.description("Create a new folder")
|
|
154
|
+
.requiredOption("--name <name>", "Folder name")
|
|
155
|
+
.option("--parent <id>", "Parent folder ID")
|
|
156
|
+
.option("--account <name>", "Account name", "default")
|
|
157
|
+
.action(async (opts) => {
|
|
158
|
+
const { clientManager } = resolve();
|
|
159
|
+
await handleMkdir(clientManager, opts.account, opts.name, opts.parent);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
gdrive
|
|
163
|
+
.command("list-folder")
|
|
164
|
+
.description("List contents of a specific folder")
|
|
165
|
+
.requiredOption("--id <id>", "Folder ID")
|
|
166
|
+
.option("--max-results <n>", "Maximum items to return", "50")
|
|
167
|
+
.option("--account <name>", "Account name", "default")
|
|
168
|
+
.action(async (opts) => {
|
|
169
|
+
const { clientManager } = resolve();
|
|
170
|
+
await handleListFolder(clientManager, opts.account, opts.id, parseInt(opts.maxResults));
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
gdrive
|
|
174
|
+
.command("search")
|
|
175
|
+
.description("Full-text search across Drive")
|
|
176
|
+
.requiredOption("--query <query>", "Search query")
|
|
177
|
+
.option("--max-results <n>", "Maximum results to return", "20")
|
|
178
|
+
.option("--account <name>", "Account name", "default")
|
|
179
|
+
.action(async (opts) => {
|
|
180
|
+
const { clientManager } = resolve();
|
|
181
|
+
await handleSearch(clientManager, opts.account, opts.query, parseInt(opts.maxResults));
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
gdrive
|
|
185
|
+
.command("share")
|
|
186
|
+
.description("Share a file with a user")
|
|
187
|
+
.requiredOption("--id <id>", "File ID")
|
|
188
|
+
.requiredOption("--email <email>", "Email to share with")
|
|
189
|
+
.option("--role <role>", "Permission role: reader, writer, commenter", "reader")
|
|
190
|
+
.option("--account <name>", "Account name", "default")
|
|
191
|
+
.action(async (opts) => {
|
|
192
|
+
const { clientManager } = resolve();
|
|
193
|
+
await handleShare(clientManager, opts.account, opts.id, opts.email, opts.role);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
gdrive
|
|
197
|
+
.command("unshare")
|
|
198
|
+
.description("Remove a permission from a file")
|
|
199
|
+
.requiredOption("--id <id>", "File ID")
|
|
200
|
+
.requiredOption("--permission-id <pid>", "Permission ID to remove")
|
|
201
|
+
.option("--account <name>", "Account name", "default")
|
|
202
|
+
.action(async (opts) => {
|
|
203
|
+
const { clientManager } = resolve();
|
|
204
|
+
await handleUnshare(clientManager, opts.account, opts.id, opts.permissionId);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
gdrive
|
|
208
|
+
.command("permissions")
|
|
209
|
+
.description("List permissions on a file")
|
|
210
|
+
.requiredOption("--id <id>", "File ID")
|
|
211
|
+
.option("--account <name>", "Account name", "default")
|
|
212
|
+
.action(async (opts) => {
|
|
213
|
+
const { clientManager } = resolve();
|
|
214
|
+
await handlePermissions(clientManager, opts.account, opts.id);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
gdrive
|
|
218
|
+
.command("about")
|
|
219
|
+
.description("Show storage quota and user info")
|
|
220
|
+
.option("--account <name>", "Account name", "default")
|
|
221
|
+
.action(async (opts) => {
|
|
222
|
+
const { clientManager } = resolve();
|
|
223
|
+
await handleAbout(clientManager, opts.account);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { OAuthClientManager } from "@digitalpresence/cliclaw-auth";
|
|
3
|
+
import { handleAuth } from "../gmail/auth.js";
|
|
4
|
+
import { handleAccounts } from "../gmail/accounts.js";
|
|
5
|
+
import { handleInbox, handleSearch } from "../gmail/inbox.js";
|
|
6
|
+
import { handleGet, handleDownloadAttachment } from "../gmail/get.js";
|
|
7
|
+
import { handleSend, handleReply, handleForward } from "../gmail/send.js";
|
|
8
|
+
import { handleModify } from "../gmail/modify.js";
|
|
9
|
+
import { handleDraftList, handleDraftCreate, handleDraftUpdate, handleDraftDelete, handleDraftSend } from "../gmail/drafts.js";
|
|
10
|
+
import { handleLabelsList, handleLabelCreate, handleLabelDelete } from "../gmail/labels.js";
|
|
11
|
+
import { handleThreadList, handleThreadGet } from "../gmail/threads.js";
|
|
12
|
+
|
|
13
|
+
type ClientFactory = () => { clientManager: OAuthClientManager; port: number };
|
|
14
|
+
|
|
15
|
+
export function registerGmailCommands(program: Command, getClient: ClientFactory): void {
|
|
16
|
+
// Cache so we only call the factory once
|
|
17
|
+
let cached: { clientManager: OAuthClientManager; port: number } | null = null;
|
|
18
|
+
function resolve() {
|
|
19
|
+
if (!cached) cached = getClient();
|
|
20
|
+
return cached;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const gmail = program.command("gmail").description("Gmail commands");
|
|
24
|
+
|
|
25
|
+
gmail
|
|
26
|
+
.command("auth")
|
|
27
|
+
.description("Authenticate with Gmail via Google OAuth2")
|
|
28
|
+
.option("--account <name>", "Account name", "default")
|
|
29
|
+
.action(async (opts) => {
|
|
30
|
+
const { clientManager, port } = resolve();
|
|
31
|
+
await handleAuth(clientManager, port, opts.account);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
gmail
|
|
35
|
+
.command("accounts")
|
|
36
|
+
.description("List authenticated Gmail accounts")
|
|
37
|
+
.action(async () => {
|
|
38
|
+
const { clientManager } = resolve();
|
|
39
|
+
await handleAccounts(clientManager);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
gmail
|
|
43
|
+
.command("inbox")
|
|
44
|
+
.description("List recent inbox messages")
|
|
45
|
+
.option("--max-results <n>", "Maximum messages to return", "20")
|
|
46
|
+
.option("--account <name>", "Account name", "default")
|
|
47
|
+
.action(async (opts) => {
|
|
48
|
+
const { clientManager } = resolve();
|
|
49
|
+
await handleInbox(clientManager, opts.account, parseInt(opts.maxResults));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
gmail
|
|
53
|
+
.command("search")
|
|
54
|
+
.description("Search Gmail messages")
|
|
55
|
+
.requiredOption("--query <query>", "Gmail search query")
|
|
56
|
+
.option("--max-results <n>", "Maximum messages to return", "20")
|
|
57
|
+
.option("--account <name>", "Account name", "default")
|
|
58
|
+
.action(async (opts) => {
|
|
59
|
+
const { clientManager } = resolve();
|
|
60
|
+
await handleSearch(clientManager, opts.account, opts.query, parseInt(opts.maxResults));
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
gmail
|
|
64
|
+
.command("get")
|
|
65
|
+
.description("Get full message by ID")
|
|
66
|
+
.requiredOption("--id <id>", "Gmail message ID")
|
|
67
|
+
.option("--account <name>", "Account name", "default")
|
|
68
|
+
.action(async (opts) => {
|
|
69
|
+
const { clientManager } = resolve();
|
|
70
|
+
await handleGet(clientManager, opts.account, opts.id);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
gmail
|
|
74
|
+
.command("send")
|
|
75
|
+
.description("Send a new email")
|
|
76
|
+
.requiredOption("--to <address>", "Recipient email")
|
|
77
|
+
.requiredOption("--subject <subject>", "Email subject")
|
|
78
|
+
.requiredOption("--body <text>", "Plain-text body")
|
|
79
|
+
.option("--cc <addresses>", "CC recipients")
|
|
80
|
+
.option("--bcc <addresses>", "BCC recipients")
|
|
81
|
+
.option("--html-body <html>", "HTML body")
|
|
82
|
+
.option("--attachment <path>", "File attachment path (repeatable)", (val: string, prev: string[]) => prev.concat(val), [] as string[])
|
|
83
|
+
.option("--account <name>", "Account name", "default")
|
|
84
|
+
.action(async (opts) => {
|
|
85
|
+
const { clientManager } = resolve();
|
|
86
|
+
await handleSend(
|
|
87
|
+
clientManager,
|
|
88
|
+
opts.account,
|
|
89
|
+
opts.to,
|
|
90
|
+
opts.subject,
|
|
91
|
+
opts.body,
|
|
92
|
+
opts.cc,
|
|
93
|
+
opts.bcc,
|
|
94
|
+
opts.htmlBody,
|
|
95
|
+
opts.attachment.length > 0 ? opts.attachment : undefined,
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
gmail
|
|
100
|
+
.command("reply")
|
|
101
|
+
.description("Reply to an existing message")
|
|
102
|
+
.requiredOption("--id <id>", "Message ID to reply to")
|
|
103
|
+
.requiredOption("--body <text>", "Reply body")
|
|
104
|
+
.option("--reply-all", "Reply to all recipients")
|
|
105
|
+
.option("--html-body <html>", "HTML reply body")
|
|
106
|
+
.option("--attachment <path>", "File attachment path (repeatable)", (val: string, prev: string[]) => prev.concat(val), [] as string[])
|
|
107
|
+
.option("--account <name>", "Account name", "default")
|
|
108
|
+
.action(async (opts) => {
|
|
109
|
+
const { clientManager } = resolve();
|
|
110
|
+
await handleReply(
|
|
111
|
+
clientManager,
|
|
112
|
+
opts.account,
|
|
113
|
+
opts.id,
|
|
114
|
+
opts.body,
|
|
115
|
+
opts.replyAll,
|
|
116
|
+
opts.htmlBody,
|
|
117
|
+
opts.attachment.length > 0 ? opts.attachment : undefined,
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
gmail
|
|
122
|
+
.command("forward")
|
|
123
|
+
.description("Forward a message")
|
|
124
|
+
.requiredOption("--id <id>", "Message ID to forward")
|
|
125
|
+
.requiredOption("--to <address>", "Recipient to forward to")
|
|
126
|
+
.option("--body <text>", "Introductory note")
|
|
127
|
+
.option("--attachment <path>", "File attachment path (repeatable)", (val: string, prev: string[]) => prev.concat(val), [] as string[])
|
|
128
|
+
.option("--account <name>", "Account name", "default")
|
|
129
|
+
.action(async (opts) => {
|
|
130
|
+
const { clientManager } = resolve();
|
|
131
|
+
await handleForward(
|
|
132
|
+
clientManager,
|
|
133
|
+
opts.account,
|
|
134
|
+
opts.id,
|
|
135
|
+
opts.to,
|
|
136
|
+
opts.body,
|
|
137
|
+
opts.attachment.length > 0 ? opts.attachment : undefined,
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
gmail
|
|
142
|
+
.command("modify")
|
|
143
|
+
.description("Modify message state (read/unread/archive/trash/star/labels)")
|
|
144
|
+
.requiredOption("--id <id>", "Message ID")
|
|
145
|
+
.requiredOption("--action <action>", "Action: mark_read, mark_unread, archive, trash, untrash, star, unstar, add_labels, remove_labels")
|
|
146
|
+
.option("--label-ids <ids...>", "Label IDs for add_labels/remove_labels")
|
|
147
|
+
.option("--account <name>", "Account name", "default")
|
|
148
|
+
.action(async (opts) => {
|
|
149
|
+
const { clientManager } = resolve();
|
|
150
|
+
await handleModify(clientManager, opts.account, opts.id, opts.action, opts.labelIds);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
gmail
|
|
154
|
+
.command("download-attachment")
|
|
155
|
+
.description("Download an email attachment")
|
|
156
|
+
.requiredOption("--id <id>", "Message ID")
|
|
157
|
+
.requiredOption("--attachment-id <aid>", "Attachment ID")
|
|
158
|
+
.requiredOption("--filename <name>", "Filename to save as")
|
|
159
|
+
.requiredOption("--save-dir <dir>", "Directory to save to")
|
|
160
|
+
.option("--account <name>", "Account name", "default")
|
|
161
|
+
.action(async (opts) => {
|
|
162
|
+
const { clientManager } = resolve();
|
|
163
|
+
await handleDownloadAttachment(
|
|
164
|
+
clientManager,
|
|
165
|
+
opts.account,
|
|
166
|
+
opts.id,
|
|
167
|
+
opts.attachmentId,
|
|
168
|
+
opts.filename,
|
|
169
|
+
opts.saveDir,
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Drafts subcommand group
|
|
174
|
+
const drafts = gmail.command("drafts").description("Draft management");
|
|
175
|
+
|
|
176
|
+
drafts
|
|
177
|
+
.command("list")
|
|
178
|
+
.description("List drafts")
|
|
179
|
+
.option("--max-results <n>", "Maximum drafts to return", "20")
|
|
180
|
+
.option("--account <name>", "Account name", "default")
|
|
181
|
+
.action(async (opts) => {
|
|
182
|
+
const { clientManager } = resolve();
|
|
183
|
+
await handleDraftList(clientManager, opts.account, parseInt(opts.maxResults));
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
drafts
|
|
187
|
+
.command("create")
|
|
188
|
+
.description("Create a new draft")
|
|
189
|
+
.requiredOption("--to <address>", "Recipient email")
|
|
190
|
+
.requiredOption("--subject <subject>", "Email subject")
|
|
191
|
+
.requiredOption("--body <text>", "Plain-text body")
|
|
192
|
+
.option("--cc <addresses>", "CC recipients")
|
|
193
|
+
.option("--bcc <addresses>", "BCC recipients")
|
|
194
|
+
.option("--account <name>", "Account name", "default")
|
|
195
|
+
.action(async (opts) => {
|
|
196
|
+
const { clientManager } = resolve();
|
|
197
|
+
await handleDraftCreate(clientManager, opts.account, opts.to, opts.subject, opts.body, opts.cc, opts.bcc);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
drafts
|
|
201
|
+
.command("update")
|
|
202
|
+
.description("Update an existing draft")
|
|
203
|
+
.requiredOption("--draft-id <id>", "Draft ID")
|
|
204
|
+
.requiredOption("--to <address>", "Recipient email")
|
|
205
|
+
.requiredOption("--subject <subject>", "Email subject")
|
|
206
|
+
.requiredOption("--body <text>", "Plain-text body")
|
|
207
|
+
.option("--cc <addresses>", "CC recipients")
|
|
208
|
+
.option("--bcc <addresses>", "BCC recipients")
|
|
209
|
+
.option("--account <name>", "Account name", "default")
|
|
210
|
+
.action(async (opts) => {
|
|
211
|
+
const { clientManager } = resolve();
|
|
212
|
+
await handleDraftUpdate(clientManager, opts.account, opts.draftId, opts.to, opts.subject, opts.body, opts.cc, opts.bcc);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
drafts
|
|
216
|
+
.command("delete")
|
|
217
|
+
.description("Delete a draft")
|
|
218
|
+
.requiredOption("--draft-id <id>", "Draft ID")
|
|
219
|
+
.option("--account <name>", "Account name", "default")
|
|
220
|
+
.action(async (opts) => {
|
|
221
|
+
const { clientManager } = resolve();
|
|
222
|
+
await handleDraftDelete(clientManager, opts.account, opts.draftId);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
drafts
|
|
226
|
+
.command("send")
|
|
227
|
+
.description("Send a draft")
|
|
228
|
+
.requiredOption("--draft-id <id>", "Draft ID")
|
|
229
|
+
.option("--account <name>", "Account name", "default")
|
|
230
|
+
.action(async (opts) => {
|
|
231
|
+
const { clientManager } = resolve();
|
|
232
|
+
await handleDraftSend(clientManager, opts.account, opts.draftId);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Labels subcommand group
|
|
236
|
+
const labels = gmail.command("labels").description("Label management");
|
|
237
|
+
|
|
238
|
+
labels
|
|
239
|
+
.command("list")
|
|
240
|
+
.description("List all labels")
|
|
241
|
+
.option("--account <name>", "Account name", "default")
|
|
242
|
+
.action(async (opts) => {
|
|
243
|
+
const { clientManager } = resolve();
|
|
244
|
+
await handleLabelsList(clientManager, opts.account);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
labels
|
|
248
|
+
.command("create")
|
|
249
|
+
.description("Create a new label")
|
|
250
|
+
.requiredOption("--name <name>", "Label name")
|
|
251
|
+
.option("--account <name>", "Account name", "default")
|
|
252
|
+
.action(async (opts) => {
|
|
253
|
+
const { clientManager } = resolve();
|
|
254
|
+
await handleLabelCreate(clientManager, opts.account, opts.name);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
labels
|
|
258
|
+
.command("delete")
|
|
259
|
+
.description("Delete a label")
|
|
260
|
+
.requiredOption("--label-id <id>", "Label ID")
|
|
261
|
+
.option("--account <name>", "Account name", "default")
|
|
262
|
+
.action(async (opts) => {
|
|
263
|
+
const { clientManager } = resolve();
|
|
264
|
+
await handleLabelDelete(clientManager, opts.account, opts.labelId);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// Threads subcommand group
|
|
268
|
+
const threads = gmail.command("threads").description("Thread management");
|
|
269
|
+
|
|
270
|
+
threads
|
|
271
|
+
.command("list")
|
|
272
|
+
.description("List threads")
|
|
273
|
+
.option("--query <query>", "Gmail search query")
|
|
274
|
+
.option("--max-results <n>", "Maximum threads to return", "20")
|
|
275
|
+
.option("--account <name>", "Account name", "default")
|
|
276
|
+
.action(async (opts) => {
|
|
277
|
+
const { clientManager } = resolve();
|
|
278
|
+
await handleThreadList(clientManager, opts.account, parseInt(opts.maxResults), opts.query);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
threads
|
|
282
|
+
.command("get")
|
|
283
|
+
.description("Get all messages in a thread")
|
|
284
|
+
.requiredOption("--thread-id <id>", "Thread ID")
|
|
285
|
+
.option("--account <name>", "Account name", "default")
|
|
286
|
+
.action(async (opts) => {
|
|
287
|
+
const { clientManager } = resolve();
|
|
288
|
+
await handleThreadGet(clientManager, opts.account, opts.threadId);
|
|
289
|
+
});
|
|
290
|
+
}
|