@marcfargas/go-easy 0.0.1 → 0.2.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +21 -0
  3. package/README.md +220 -0
  4. package/dist/auth.d.ts +41 -0
  5. package/dist/auth.d.ts.map +1 -0
  6. package/dist/auth.js +91 -0
  7. package/dist/auth.js.map +1 -0
  8. package/dist/bin/calendar.d.ts +17 -0
  9. package/dist/bin/calendar.d.ts.map +1 -0
  10. package/dist/bin/calendar.js +162 -0
  11. package/dist/bin/calendar.js.map +1 -0
  12. package/dist/bin/drive.d.ts +18 -0
  13. package/dist/bin/drive.d.ts.map +1 -0
  14. package/dist/bin/drive.js +203 -0
  15. package/dist/bin/drive.js.map +1 -0
  16. package/dist/bin/gmail.d.ts +20 -0
  17. package/dist/bin/gmail.d.ts.map +1 -0
  18. package/dist/bin/gmail.js +171 -0
  19. package/dist/bin/gmail.js.map +1 -0
  20. package/dist/calendar/helpers.d.ts +23 -0
  21. package/dist/calendar/helpers.d.ts.map +1 -0
  22. package/dist/calendar/helpers.js +69 -0
  23. package/dist/calendar/helpers.js.map +1 -0
  24. package/dist/calendar/index.d.ts +64 -0
  25. package/dist/calendar/index.d.ts.map +1 -0
  26. package/dist/calendar/index.js +202 -0
  27. package/dist/calendar/index.js.map +1 -0
  28. package/dist/calendar/types.d.ts +107 -0
  29. package/dist/calendar/types.d.ts.map +1 -0
  30. package/dist/calendar/types.js +5 -0
  31. package/dist/calendar/types.js.map +1 -0
  32. package/dist/drive/helpers.d.ts +22 -0
  33. package/dist/drive/helpers.d.ts.map +1 -0
  34. package/dist/drive/helpers.js +85 -0
  35. package/dist/drive/helpers.js.map +1 -0
  36. package/dist/drive/index.d.ts +114 -0
  37. package/dist/drive/index.d.ts.map +1 -0
  38. package/dist/drive/index.js +418 -0
  39. package/dist/drive/index.js.map +1 -0
  40. package/dist/drive/types.d.ts +91 -0
  41. package/dist/drive/types.d.ts.map +1 -0
  42. package/dist/drive/types.js +5 -0
  43. package/dist/drive/types.js.map +1 -0
  44. package/dist/errors.d.ts +34 -0
  45. package/dist/errors.d.ts.map +1 -0
  46. package/dist/errors.js +53 -0
  47. package/dist/errors.js.map +1 -0
  48. package/dist/gmail/helpers.d.ts +52 -0
  49. package/dist/gmail/helpers.d.ts.map +1 -0
  50. package/dist/gmail/helpers.js +282 -0
  51. package/dist/gmail/helpers.js.map +1 -0
  52. package/dist/gmail/index.d.ts +86 -0
  53. package/dist/gmail/index.d.ts.map +1 -0
  54. package/dist/gmail/index.js +395 -0
  55. package/dist/gmail/index.js.map +1 -0
  56. package/dist/gmail/types.d.ts +138 -0
  57. package/dist/gmail/types.d.ts.map +1 -0
  58. package/dist/gmail/types.js +5 -0
  59. package/dist/gmail/types.js.map +1 -0
  60. package/dist/index.d.ts +22 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +24 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/safety.d.ts +58 -0
  65. package/dist/safety.d.ts.map +1 -0
  66. package/dist/safety.js +61 -0
  67. package/dist/safety.js.map +1 -0
  68. package/package.json +48 -7
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # @marcfargas/go-easy
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`5f424e1`](https://github.com/marcfargas/go-easy/commit/5f424e16c3c9971c2be196725a5d9c1d7e88633b) Thanks [@marcfargas](https://github.com/marcfargas)! - Initial release — Gmail, Drive & Calendar APIs for AI agents and humans.
8
+
9
+ - Gmail: search, getMessage, getThread, send, reply, forward, createDraft, sendDraft, listDrafts, listLabels, batchModifyLabels, getAttachmentContent, getProfile
10
+ - Drive: listFiles, searchFiles, getFile, downloadFile, exportFile, uploadFile, createFolder, moveFile, renameFile, copyFile, trashFile, listPermissions, shareFile, unshareFile
11
+ - Calendar: listCalendars, listEvents, getEvent, createEvent, updateEvent, deleteEvent, queryFreeBusy
12
+ - Gateway CLIs: go-gmail, go-drive, go-calendar (JSON output, --confirm safety)
13
+ - Safety model: READ/WRITE/DESTRUCTIVE operation classification
14
+ - Auth: multi-account OAuth2 with per-service token stores
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marc Fargas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # go-easy 🟢
2
+
3
+ > Google APIs made easy — Gmail, Drive & Calendar. For AI agents and humans.
4
+
5
+ Thin TypeScript wrappers over Google's individual `@googleapis/*` packages with:
6
+ - **Simple auth** — multi-account OAuth2 with token import from existing tools
7
+ - **Agent-friendly types** — structured `GmailMessage`, `DriveFile`, `CalendarEvent`
8
+ - **Safety guards** — destructive operations (send, share, delete) require explicit confirmation
9
+ - **JSON gateways** — CLI tools that always output structured JSON
10
+ - **Progressive skills** — designed for AI agent consumption (pi coding agent)
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ # As a library
16
+ npm install @marcfargas/go-easy
17
+
18
+ # As CLI tools (no install needed)
19
+ npx go-gmail you@example.com search "is:unread"
20
+ npx go-drive you@example.com ls
21
+ npx go-calendar you@example.com events primary
22
+ ```
23
+
24
+ Requires **Node.js ≥ 20**.
25
+
26
+ ## Auth Setup
27
+
28
+ go-easy uses OAuth2 tokens stored per-service. Each service reads from its own token store:
29
+
30
+ | Service | Token store |
31
+ |---|---|
32
+ | Gmail | `~/.gmcli/accounts.json` |
33
+ | Drive | `~/.gdcli/accounts.json` |
34
+ | Calendar | `~/.gccli/accounts.json` |
35
+
36
+ Each `accounts.json` file contains an array of accounts:
37
+
38
+ ```json
39
+ [
40
+ {
41
+ "email": "you@example.com",
42
+ "oauth2": {
43
+ "clientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
44
+ "clientSecret": "YOUR_CLIENT_SECRET",
45
+ "refreshToken": "YOUR_REFRESH_TOKEN"
46
+ }
47
+ }
48
+ ]
49
+ ```
50
+
51
+ To obtain credentials:
52
+ 1. Create a project in [Google Cloud Console](https://console.cloud.google.com/)
53
+ 2. Enable the Gmail, Drive, and/or Calendar APIs
54
+ 3. Create OAuth2 credentials (Desktop application)
55
+ 4. Use the OAuth2 playground or a local flow to obtain a refresh token
56
+ 5. Place the token in the appropriate `accounts.json` file
57
+
58
+ ## Quick Start
59
+
60
+ ```ts
61
+ import { getAuth } from '@marcfargas/go-easy/auth';
62
+ import { search, send } from '@marcfargas/go-easy/gmail';
63
+
64
+ const auth = await getAuth('gmail', 'you@example.com');
65
+
66
+ // Search (READ — no safety gate)
67
+ const results = await search(auth, { query: 'is:unread from:client' });
68
+ console.log(results.items);
69
+
70
+ // Send (DESTRUCTIVE — requires safety context)
71
+ import { setSafetyContext } from '@marcfargas/go-easy';
72
+
73
+ setSafetyContext({
74
+ confirm: async (op) => {
75
+ console.log(`⚠️ ${op.description}`);
76
+ return true; // or prompt the user
77
+ },
78
+ });
79
+
80
+ await send(auth, {
81
+ to: 'client@example.com',
82
+ subject: 'Invoice attached',
83
+ html: '<h1>Invoice</h1><p>Please find attached.</p>',
84
+ attachments: ['./invoice.pdf'],
85
+ });
86
+ ```
87
+
88
+ ## Gateway CLIs
89
+
90
+ All gateway CLIs output JSON to stdout and work via `npx`:
91
+
92
+ ```bash
93
+ # Gmail
94
+ npx go-gmail you@example.com search "is:unread" --max=10
95
+ npx go-gmail you@example.com get <messageId>
96
+ npx go-gmail you@example.com send --to=x@y.com --subject="Hi" --body="Hello" --confirm
97
+
98
+ # Drive
99
+ npx go-drive you@example.com ls
100
+ npx go-drive you@example.com search "quarterly report"
101
+ npx go-drive you@example.com upload ./file.pdf --folder=<folderId>
102
+
103
+ # Calendar
104
+ npx go-calendar you@example.com events primary --from=2026-02-01T00:00:00Z
105
+ npx go-calendar you@example.com create primary --summary="Meeting" --start=... --end=...
106
+ npx go-calendar you@example.com freebusy primary --from=... --to=...
107
+ ```
108
+
109
+ Destructive operations require `--confirm`. Without it, they show what *would* happen and exit with code 2.
110
+
111
+ ## Services
112
+
113
+ | Service | Module | Gateway | Status |
114
+ |---------|--------|---------|--------|
115
+ | Gmail | `@marcfargas/go-easy/gmail` | `npx go-gmail` | ✅ Ready |
116
+ | Drive | `@marcfargas/go-easy/drive` | `npx go-drive` | ✅ Ready |
117
+ | Calendar | `@marcfargas/go-easy/calendar` | `npx go-calendar` | ✅ Ready |
118
+
119
+ ### Gmail
120
+
121
+ | Function | Safety | Description |
122
+ |---|---|---|
123
+ | `search` | READ | Search messages by Gmail query |
124
+ | `getMessage` | READ | Get a single message with parsed fields |
125
+ | `getThread` | READ | Get a full conversation thread |
126
+ | `listLabels` | READ | List all labels |
127
+ | `getAttachmentContent` | READ | Download an attachment as Buffer |
128
+ | `getProfile` | READ | Get the authenticated email address |
129
+ | `createDraft` | WRITE | Create a draft (no send) |
130
+ | `listDrafts` | READ | List existing drafts |
131
+ | `batchModifyLabels` | WRITE | Add/remove labels on multiple messages |
132
+ | `send` | ⚠️ DESTRUCTIVE | Send a new email |
133
+ | `reply` | ⚠️ DESTRUCTIVE | Reply to a message (preserves thread) |
134
+ | `forward` | ⚠️ DESTRUCTIVE | Forward a message with attachments |
135
+ | `sendDraft` | ⚠️ DESTRUCTIVE | Send an existing draft |
136
+
137
+ ### Drive
138
+
139
+ | Function | Safety | Description |
140
+ |---|---|---|
141
+ | `listFiles` | READ | List folder contents or query by metadata |
142
+ | `searchFiles` | READ | Full-text search inside file contents |
143
+ | `getFile` | READ | Get file metadata by ID |
144
+ | `downloadFile` | READ | Download binary files as Buffer |
145
+ | `exportFile` | READ | Export Workspace files (Docs → pdf/docx, Sheets → xlsx/csv, etc.) |
146
+ | `listPermissions` | READ | List sharing permissions on a file |
147
+ | `uploadFile` | WRITE | Upload a local file |
148
+ | `createFolder` | WRITE | Create a folder |
149
+ | `moveFile` | WRITE | Move a file to a different folder |
150
+ | `renameFile` | WRITE | Rename a file |
151
+ | `copyFile` | WRITE | Copy a file |
152
+ | `trashFile` | ⚠️ DESTRUCTIVE | Trash a file |
153
+ | `shareFile` | ⚠️ DESTRUCTIVE* | Share a file (*public sharing only; user/group is WRITE) |
154
+ | `unshareFile` | ⚠️ DESTRUCTIVE | Remove a sharing permission |
155
+
156
+ ### Calendar
157
+
158
+ | Function | Safety | Description |
159
+ |---|---|---|
160
+ | `listCalendars` | READ | List all calendars for the account |
161
+ | `listEvents` | READ | List events with time range, search, pagination |
162
+ | `getEvent` | READ | Get a single event by ID |
163
+ | `queryFreeBusy` | READ | Check availability across calendars |
164
+ | `createEvent` | WRITE | Create an event (with attendees, all-day, location) |
165
+ | `updateEvent` | WRITE | Update an existing event |
166
+ | `deleteEvent` | ⚠️ DESTRUCTIVE | Delete an event (warns about attendee cancellation) |
167
+
168
+ ## Safety Model
169
+
170
+ Operations are classified into three levels:
171
+
172
+ | Level | Gate | Examples |
173
+ |-------|------|----------|
174
+ | **READ** | None | search, getMessage, listLabels |
175
+ | **WRITE** | Logged | createDraft, batchModifyLabels, upload |
176
+ | **DESTRUCTIVE** | Blocked unless confirmed | send, reply, forward, share, delete |
177
+
178
+ Set up a `SafetyContext` at startup to handle confirmation prompts.
179
+ Without one, all destructive operations are blocked by default.
180
+
181
+ ## Module Structure
182
+
183
+ go-easy uses **subpath exports** — import only what you need:
184
+
185
+ ```ts
186
+ // Subpath imports (recommended)
187
+ import { getAuth } from '@marcfargas/go-easy/auth';
188
+ import { search, send } from '@marcfargas/go-easy/gmail';
189
+ import { listFiles, upload } from '@marcfargas/go-easy/drive';
190
+ import { listEvents, createEvent } from '@marcfargas/go-easy/calendar';
191
+ import { setSafetyContext } from '@marcfargas/go-easy'; // root: safety, errors, shared utils
192
+ ```
193
+
194
+ | Import path | What's in it |
195
+ |---|---|
196
+ | `@marcfargas/go-easy` | Safety context, errors, plus `gmail`/`drive`/`calendar` as namespaces |
197
+ | `@marcfargas/go-easy/auth` | `getAuth`, `listAccounts`, `clearAuthCache` |
198
+ | `@marcfargas/go-easy/gmail` | All Gmail operations |
199
+ | `@marcfargas/go-easy/drive` | All Drive operations |
200
+ | `@marcfargas/go-easy/calendar` | All Calendar operations |
201
+
202
+ The root export also re-exports each service as a namespace, so `import { gmail } from '@marcfargas/go-easy'` works if you prefer a single import.
203
+
204
+ ## Development
205
+
206
+ ```bash
207
+ npm install # install deps
208
+ npm run build # compile TypeScript
209
+ npm test # run tests (vitest)
210
+ npm run lint # type-check without emitting
211
+ npm run dev # watch mode
212
+ ```
213
+
214
+ ## Contributing
215
+
216
+ Found a bug or have a feature request? [Open an issue](https://github.com/marcfargas/go-easy/issues).
217
+
218
+ ## License
219
+
220
+ MIT
package/dist/auth.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Auth module — OAuth2 client factory with multi-account support.
3
+ *
4
+ * Phase 1 (MVP): Import tokens from existing CLI stores:
5
+ * ~/.gmcli/accounts.json → Gmail tokens
6
+ * ~/.gdcli/accounts.json → Drive tokens
7
+ * ~/.gccli/accounts.json → Calendar tokens
8
+ *
9
+ * Phase 2 (post-migration): Unified token store at ~/.go-easy/
10
+ * with combined scopes per account (single OAuth consent).
11
+ *
12
+ * Each CLI token only works for its service's scopes. The library
13
+ * routes internally — callers specify account (email), and each
14
+ * service module gets the right OAuth2Client.
15
+ */
16
+ import { OAuth2Client } from 'google-auth-library';
17
+ /** Services we can load tokens for */
18
+ export type GoogleService = 'gmail' | 'drive' | 'calendar';
19
+ /**
20
+ * Get an OAuth2Client for a specific service and account.
21
+ *
22
+ * @param service - Which Google service (determines which CLI token to use)
23
+ * @param account - Email address (defaults to first account in the store)
24
+ * @returns Configured OAuth2Client with refresh token set
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { getAuth } from 'go-easy/auth';
29
+ * const auth = await getAuth('gmail', 'marc@blegal.eu');
30
+ * ```
31
+ */
32
+ export declare function getAuth(service: GoogleService, account?: string): Promise<OAuth2Client>;
33
+ /**
34
+ * List available accounts for a service.
35
+ */
36
+ export declare function listAccounts(service: GoogleService): Promise<string[]>;
37
+ /**
38
+ * Clear the client cache. Useful for tests or token rotation.
39
+ */
40
+ export declare function clearAuthCache(): void;
41
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,sCAAsC;AACtC,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAwC3D;;;;;;;;;;;;GAYG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CA+BvB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAG5E;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
package/dist/auth.js ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Auth module — OAuth2 client factory with multi-account support.
3
+ *
4
+ * Phase 1 (MVP): Import tokens from existing CLI stores:
5
+ * ~/.gmcli/accounts.json → Gmail tokens
6
+ * ~/.gdcli/accounts.json → Drive tokens
7
+ * ~/.gccli/accounts.json → Calendar tokens
8
+ *
9
+ * Phase 2 (post-migration): Unified token store at ~/.go-easy/
10
+ * with combined scopes per account (single OAuth consent).
11
+ *
12
+ * Each CLI token only works for its service's scopes. The library
13
+ * routes internally — callers specify account (email), and each
14
+ * service module gets the right OAuth2Client.
15
+ */
16
+ import { readFile } from 'node:fs/promises';
17
+ import { join } from 'node:path';
18
+ import { homedir } from 'node:os';
19
+ import { OAuth2Client } from 'google-auth-library';
20
+ import { AuthError } from './errors.js';
21
+ /** Map service → CLI config directory name */
22
+ const CLI_DIRS = {
23
+ gmail: '.gmcli',
24
+ drive: '.gdcli',
25
+ calendar: '.gccli',
26
+ };
27
+ /** Cache: "service:email" → OAuth2Client */
28
+ const clientCache = new Map();
29
+ /**
30
+ * Load accounts from a CLI's accounts.json file.
31
+ */
32
+ async function loadCliAccounts(service) {
33
+ const dir = CLI_DIRS[service];
34
+ const accountsPath = join(homedir(), dir, 'accounts.json');
35
+ try {
36
+ const raw = await readFile(accountsPath, 'utf-8');
37
+ return JSON.parse(raw);
38
+ }
39
+ catch (err) {
40
+ throw new AuthError(`Cannot read ${service} accounts from ${accountsPath}. Is the CLI configured?`, err);
41
+ }
42
+ }
43
+ /**
44
+ * Get an OAuth2Client for a specific service and account.
45
+ *
46
+ * @param service - Which Google service (determines which CLI token to use)
47
+ * @param account - Email address (defaults to first account in the store)
48
+ * @returns Configured OAuth2Client with refresh token set
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * import { getAuth } from 'go-easy/auth';
53
+ * const auth = await getAuth('gmail', 'marc@blegal.eu');
54
+ * ```
55
+ */
56
+ export async function getAuth(service, account) {
57
+ const accounts = await loadCliAccounts(service);
58
+ const entry = account
59
+ ? accounts.find((a) => a.email === account)
60
+ : accounts[0];
61
+ if (!entry) {
62
+ const available = accounts.map((a) => a.email).join(', ');
63
+ throw new AuthError(account
64
+ ? `Account "${account}" not found for ${service}. Available: ${available}`
65
+ : `No accounts configured for ${service}`);
66
+ }
67
+ const cacheKey = `${service}:${entry.email}`;
68
+ const cached = clientCache.get(cacheKey);
69
+ if (cached)
70
+ return cached;
71
+ const oauth2 = new OAuth2Client(entry.oauth2.clientId, entry.oauth2.clientSecret);
72
+ oauth2.setCredentials({
73
+ refresh_token: entry.oauth2.refreshToken,
74
+ });
75
+ clientCache.set(cacheKey, oauth2);
76
+ return oauth2;
77
+ }
78
+ /**
79
+ * List available accounts for a service.
80
+ */
81
+ export async function listAccounts(service) {
82
+ const accounts = await loadCliAccounts(service);
83
+ return accounts.map((a) => a.email);
84
+ }
85
+ /**
86
+ * Clear the client cache. Useful for tests or token rotation.
87
+ */
88
+ export function clearAuthCache() {
89
+ clientCache.clear();
90
+ }
91
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAexC,8CAA8C;AAC9C,MAAM,QAAQ,GAAkC;IAC9C,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,QAAQ;CACnB,CAAC;AAEF,4CAA4C;AAC5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEpD;;GAEG;AACH,KAAK,UAAU,eAAe,CAAC,OAAsB;IACnD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,eAAe,CAAC,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,SAAS,CACjB,eAAe,OAAO,kBAAkB,YAAY,0BAA0B,EAC9E,GAAG,CACJ,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAsB,EACtB,OAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,OAAO;QACnB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC;QAC3C,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEhB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,IAAI,SAAS,CACjB,OAAO;YACL,CAAC,CAAC,YAAY,OAAO,mBAAmB,OAAO,gBAAgB,SAAS,EAAE;YAC1E,CAAC,CAAC,8BAA8B,OAAO,EAAE,CAC5C,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,MAAM,GAAG,IAAI,YAAY,CAC7B,KAAK,CAAC,MAAM,CAAC,QAAQ,EACrB,KAAK,CAAC,MAAM,CAAC,YAAY,CAC1B,CAAC;IAEF,MAAM,CAAC,cAAc,CAAC;QACpB,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY;KACzC,CAAC,CAAC;IAEH,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB;IACvD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC"}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * go-calendar — Gateway CLI for Google Calendar operations.
4
+ *
5
+ * Always outputs JSON. Designed for agent consumption.
6
+ *
7
+ * Usage:
8
+ * go-calendar <account> <command> [args...]
9
+ * go-calendar marc@blegal.eu calendars
10
+ * go-calendar marc@blegal.eu events primary --from=2026-02-01T00:00:00Z
11
+ * go-calendar marc@blegal.eu create primary --summary="Meeting" --start=... --end=...
12
+ *
13
+ * Safety:
14
+ * Destructive operations (delete) require --confirm flag.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=calendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../src/bin/calendar.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * go-calendar — Gateway CLI for Google Calendar operations.
4
+ *
5
+ * Always outputs JSON. Designed for agent consumption.
6
+ *
7
+ * Usage:
8
+ * go-calendar <account> <command> [args...]
9
+ * go-calendar marc@blegal.eu calendars
10
+ * go-calendar marc@blegal.eu events primary --from=2026-02-01T00:00:00Z
11
+ * go-calendar marc@blegal.eu create primary --summary="Meeting" --start=... --end=...
12
+ *
13
+ * Safety:
14
+ * Destructive operations (delete) require --confirm flag.
15
+ */
16
+ import { getAuth } from '../auth.js';
17
+ import { setSafetyContext } from '../safety.js';
18
+ import * as calendar from '../calendar/index.js';
19
+ const args = process.argv.slice(2);
20
+ function usage() {
21
+ console.log(JSON.stringify({
22
+ error: 'USAGE',
23
+ message: 'go-calendar <account> <command> [args...]',
24
+ commands: {
25
+ calendars: 'go-calendar <account> calendars',
26
+ events: 'go-calendar <account> events <calendarId> [--from=<dt>] [--to=<dt>] [--max=N] [--query="..."]',
27
+ event: 'go-calendar <account> event <calendarId> <eventId>',
28
+ create: 'go-calendar <account> create <calendarId> --summary="..." --start=<dt> --end=<dt> [--description="..."] [--location="..."] [--attendees=a@b,c@d] [--all-day] [--tz=<tz>]',
29
+ update: 'go-calendar <account> update <calendarId> <eventId> --summary="..." --start=<dt> --end=<dt> [--description="..."] [--location="..."] [--attendees=a@b,c@d] [--all-day] [--tz=<tz>]',
30
+ delete: 'go-calendar <account> delete <calendarId> <eventId> [--confirm]',
31
+ freebusy: 'go-calendar <account> freebusy <calendarId1,calendarId2> --from=<dt> --to=<dt>',
32
+ },
33
+ }, null, 2));
34
+ process.exit(1);
35
+ }
36
+ /** Parse --key=value flags from args */
37
+ function parseFlags(args) {
38
+ const flags = {};
39
+ for (const arg of args) {
40
+ const match = arg.match(/^--([^=]+)(?:=(.*))?$/);
41
+ if (match) {
42
+ flags[match[1]] = match[2] ?? 'true';
43
+ }
44
+ }
45
+ return flags;
46
+ }
47
+ /** Get positional args (non-flag) */
48
+ function positional(args) {
49
+ return args.filter((a) => !a.startsWith('--'));
50
+ }
51
+ async function main() {
52
+ if (args.length < 2)
53
+ usage();
54
+ const account = args[0];
55
+ const command = args[1];
56
+ const rest = args.slice(2);
57
+ const flags = parseFlags(rest);
58
+ const pos = positional(rest);
59
+ // Set up safety context: --confirm flag allows destructive ops
60
+ const hasConfirm = 'confirm' in flags;
61
+ setSafetyContext({
62
+ confirm: async (op) => {
63
+ if (!hasConfirm) {
64
+ console.log(JSON.stringify({
65
+ blocked: true,
66
+ operation: op.name,
67
+ description: op.description,
68
+ details: op.details,
69
+ hint: 'Add --confirm to execute this operation',
70
+ }, null, 2));
71
+ process.exit(2);
72
+ }
73
+ return true;
74
+ },
75
+ });
76
+ const auth = await getAuth('calendar', account);
77
+ try {
78
+ let result;
79
+ switch (command) {
80
+ case 'calendars':
81
+ result = await calendar.listCalendars(auth);
82
+ break;
83
+ case 'events':
84
+ if (!pos[0])
85
+ usage();
86
+ result = await calendar.listEvents(auth, pos[0], {
87
+ timeMin: flags.from,
88
+ timeMax: flags.to,
89
+ maxResults: flags.max ? parseInt(flags.max) : undefined,
90
+ query: flags.query,
91
+ });
92
+ break;
93
+ case 'event':
94
+ if (!pos[0] || !pos[1])
95
+ usage();
96
+ result = await calendar.getEvent(auth, pos[0], pos[1]);
97
+ break;
98
+ case 'create': {
99
+ if (!pos[0])
100
+ usage();
101
+ const createOpts = {
102
+ summary: flags.summary ?? '',
103
+ description: flags.description,
104
+ start: flags.start ?? '',
105
+ end: flags.end ?? '',
106
+ timeZone: flags.tz,
107
+ location: flags.location,
108
+ attendees: flags.attendees?.split(','),
109
+ allDay: 'all-day' in flags,
110
+ };
111
+ result = await calendar.createEvent(auth, pos[0], createOpts);
112
+ break;
113
+ }
114
+ case 'update': {
115
+ if (!pos[0] || !pos[1])
116
+ usage();
117
+ const updateOpts = {
118
+ summary: flags.summary ?? '',
119
+ description: flags.description,
120
+ start: flags.start ?? '',
121
+ end: flags.end ?? '',
122
+ timeZone: flags.tz,
123
+ location: flags.location,
124
+ attendees: flags.attendees?.split(','),
125
+ allDay: 'all-day' in flags,
126
+ };
127
+ result = await calendar.updateEvent(auth, pos[0], pos[1], updateOpts);
128
+ break;
129
+ }
130
+ case 'delete':
131
+ if (!pos[0] || !pos[1])
132
+ usage();
133
+ result = await calendar.deleteEvent(auth, pos[0], pos[1]);
134
+ break;
135
+ case 'freebusy': {
136
+ if (!pos[0] || !flags.from || !flags.to)
137
+ usage();
138
+ const calIds = pos[0].split(',');
139
+ result = await calendar.queryFreeBusy(auth, calIds, flags.from, flags.to);
140
+ break;
141
+ }
142
+ default:
143
+ usage();
144
+ }
145
+ console.log(JSON.stringify(result, null, 2));
146
+ }
147
+ catch (err) {
148
+ const e = err;
149
+ if (typeof e.toJSON === 'function') {
150
+ console.error(JSON.stringify(e.toJSON(), null, 2));
151
+ }
152
+ else {
153
+ console.error(JSON.stringify({
154
+ error: e.code ?? 'UNKNOWN',
155
+ message: e.message ?? String(err),
156
+ }, null, 2));
157
+ }
158
+ process.exit(1);
159
+ }
160
+ }
161
+ main();
162
+ //# sourceMappingURL=calendar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../src/bin/calendar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * go-drive — Gateway CLI for Google Drive operations.
4
+ *
5
+ * Always outputs JSON. Designed for agent consumption.
6
+ *
7
+ * Usage:
8
+ * go-drive <account> <command> [args...]
9
+ * go-drive marc@blegal.eu ls
10
+ * go-drive marc@blegal.eu search "quarterly report"
11
+ * go-drive marc@blegal.eu download <fileId>
12
+ * go-drive marc@blegal.eu upload ./file.pdf --folder=<folderId>
13
+ *
14
+ * Safety:
15
+ * Destructive operations (trash, share --anyone, unshare) require --confirm flag.
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=drive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.d.ts","sourceRoot":"","sources":["../../src/bin/drive.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG"}