@soederpop/luca 0.0.32 → 0.0.34

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 (86) hide show
  1. package/README.md +241 -36
  2. package/bun.lock +24 -5
  3. package/commands/build-python-bridge.ts +43 -0
  4. package/docs/apis/clients/rest.md +7 -7
  5. package/docs/apis/clients/websocket.md +23 -10
  6. package/docs/apis/features/agi/assistant.md +155 -8
  7. package/docs/apis/features/agi/assistants-manager.md +90 -22
  8. package/docs/apis/features/agi/auto-assistant.md +377 -0
  9. package/docs/apis/features/agi/browser-use.md +802 -0
  10. package/docs/apis/features/agi/claude-code.md +6 -1
  11. package/docs/apis/features/agi/conversation-history.md +7 -6
  12. package/docs/apis/features/agi/conversation.md +111 -38
  13. package/docs/apis/features/agi/docs-reader.md +35 -57
  14. package/docs/apis/features/agi/file-tools.md +163 -0
  15. package/docs/apis/features/agi/openapi.md +2 -2
  16. package/docs/apis/features/agi/skills-library.md +227 -0
  17. package/docs/apis/features/node/content-db.md +125 -4
  18. package/docs/apis/features/node/disk-cache.md +11 -11
  19. package/docs/apis/features/node/downloader.md +1 -1
  20. package/docs/apis/features/node/file-manager.md +15 -15
  21. package/docs/apis/features/node/fs.md +78 -21
  22. package/docs/apis/features/node/git.md +50 -10
  23. package/docs/apis/features/node/google-calendar.md +3 -0
  24. package/docs/apis/features/node/google-docs.md +10 -1
  25. package/docs/apis/features/node/google-drive.md +3 -0
  26. package/docs/apis/features/node/google-mail.md +214 -0
  27. package/docs/apis/features/node/google-sheets.md +3 -0
  28. package/docs/apis/features/node/ink.md +10 -10
  29. package/docs/apis/features/node/ipc-socket.md +83 -93
  30. package/docs/apis/features/node/networking.md +5 -5
  31. package/docs/apis/features/node/os.md +7 -7
  32. package/docs/apis/features/node/package-finder.md +14 -14
  33. package/docs/apis/features/node/proc.md +2 -1
  34. package/docs/apis/features/node/process-manager.md +70 -3
  35. package/docs/apis/features/node/python.md +265 -9
  36. package/docs/apis/features/node/redis.md +380 -0
  37. package/docs/apis/features/node/ui.md +13 -13
  38. package/docs/apis/servers/express.md +35 -7
  39. package/docs/apis/servers/mcp.md +3 -3
  40. package/docs/apis/servers/websocket.md +51 -8
  41. package/docs/bootstrap/CLAUDE.md +1 -1
  42. package/docs/bootstrap/SKILL.md +93 -7
  43. package/docs/examples/feature-as-tool-provider.md +143 -0
  44. package/docs/examples/python.md +42 -1
  45. package/docs/introspection.md +15 -5
  46. package/docs/tutorials/00-bootstrap.md +3 -3
  47. package/docs/tutorials/02-container.md +2 -2
  48. package/docs/tutorials/10-creating-features.md +5 -0
  49. package/docs/tutorials/13-introspection.md +12 -2
  50. package/docs/tutorials/19-python-sessions.md +401 -0
  51. package/package.json +8 -4
  52. package/src/agi/container.server.ts +8 -0
  53. package/src/agi/features/assistant.ts +18 -0
  54. package/src/agi/features/autonomous-assistant.ts +435 -0
  55. package/src/agi/features/conversation.ts +58 -6
  56. package/src/agi/features/file-tools.ts +286 -0
  57. package/src/agi/features/luca-coder.ts +643 -0
  58. package/src/bootstrap/generated.ts +705 -17
  59. package/src/cli/build-info.ts +2 -2
  60. package/src/cli/cli.ts +22 -13
  61. package/src/commands/bootstrap.ts +49 -6
  62. package/src/commands/code.ts +369 -0
  63. package/src/commands/describe.ts +7 -2
  64. package/src/commands/index.ts +1 -0
  65. package/src/commands/sandbox-mcp.ts +7 -7
  66. package/src/commands/save-api-docs.ts +1 -1
  67. package/src/container-describer.ts +4 -4
  68. package/src/container.ts +10 -19
  69. package/src/helper.ts +24 -33
  70. package/src/introspection/generated.agi.ts +3026 -590
  71. package/src/introspection/generated.node.ts +1625 -688
  72. package/src/introspection/generated.web.ts +15 -57
  73. package/src/node/container.ts +5 -0
  74. package/src/node/features/figlet-fonts.ts +597 -0
  75. package/src/node/features/fs.ts +3 -9
  76. package/src/node/features/helpers.ts +20 -0
  77. package/src/node/features/python.ts +429 -16
  78. package/src/node/features/redis.ts +446 -0
  79. package/src/node/features/ui.ts +4 -11
  80. package/src/python/bridge.py +220 -0
  81. package/src/python/generated.ts +227 -0
  82. package/src/scaffolds/generated.ts +1 -1
  83. package/test/python-session.test.ts +105 -0
  84. package/assistants/lucaExpert/CORE.md +0 -37
  85. package/assistants/lucaExpert/hooks.ts +0 -9
  86. package/assistants/lucaExpert/tools.ts +0 -177
@@ -30,6 +30,21 @@ const buffer = fs.readFile('image.png', null)
30
30
 
31
31
 
32
32
 
33
+ ### readFileSync
34
+
35
+ Synchronously reads a file and returns its contents as a string. added this method because AI Assistants are understandly confused by this deviation from 2000's era node style
36
+
37
+ **Parameters:**
38
+
39
+ | Name | Type | Required | Description |
40
+ |------|------|----------|-------------|
41
+ | `path` | `string` | ✓ | Parameter path |
42
+ | `encoding` | `BufferEncoding | null` | | Parameter encoding |
43
+
44
+ **Returns:** `string | Buffer`
45
+
46
+
47
+
33
48
  ### readFileAsync
34
49
 
35
50
  Asynchronously reads a file and returns its contents as a string.
@@ -60,7 +75,7 @@ Synchronously reads and parses a JSON file.
60
75
  |------|------|----------|-------------|
61
76
  | `path` | `string` | ✓ | The path to the JSON file |
62
77
 
63
- **Returns:** `void`
78
+ **Returns:** `any`
64
79
 
65
80
  ```ts
66
81
  const config = fs.readJson('config.json')
@@ -69,6 +84,20 @@ console.log(config.version)
69
84
 
70
85
 
71
86
 
87
+ ### readJsonSync
88
+
89
+ Read and parse a JSON file synchronously
90
+
91
+ **Parameters:**
92
+
93
+ | Name | Type | Required | Description |
94
+ |------|------|----------|-------------|
95
+ | `path` | `string` | ✓ | Parameter path |
96
+
97
+ **Returns:** `any`
98
+
99
+
100
+
72
101
  ### readJsonAsync
73
102
 
74
103
  Asynchronously reads and parses a JSON file.
@@ -79,7 +108,7 @@ Asynchronously reads and parses a JSON file.
79
108
  |------|------|----------|-------------|
80
109
  | `path` | `string` | ✓ | The path to the JSON file |
81
110
 
82
- **Returns:** `void`
111
+ **Returns:** `Promise<any>`
83
112
 
84
113
  ```ts
85
114
  const config = await fs.readJsonAsync('config.json')
@@ -98,7 +127,7 @@ Synchronously reads the contents of a directory.
98
127
  |------|------|----------|-------------|
99
128
  | `path` | `string` | ✓ | The directory path relative to the container's working directory |
100
129
 
101
- **Returns:** `void`
130
+ **Returns:** `string[]`
102
131
 
103
132
  ```ts
104
133
  const entries = fs.readdirSync('src')
@@ -117,7 +146,7 @@ Asynchronously reads the contents of a directory.
117
146
  |------|------|----------|-------------|
118
147
  | `path` | `string` | ✓ | The directory path relative to the container's working directory |
119
148
 
120
- **Returns:** `void`
149
+ **Returns:** `Promise<string[]>`
121
150
 
122
151
  ```ts
123
152
  const entries = await fs.readdir('src')
@@ -157,7 +186,7 @@ Asynchronously writes content to a file.
157
186
  | `path` | `string` | ✓ | The file path where content should be written |
158
187
  | `content` | `Buffer | string` | ✓ | The content to write to the file |
159
188
 
160
- **Returns:** `void`
189
+ **Returns:** `Promise<void>`
161
190
 
162
191
  ```ts
163
192
  await fs.writeFileAsync('output.txt', 'Hello World')
@@ -198,7 +227,7 @@ Asynchronously writes an object to a file as JSON.
198
227
  | `data` | `any` | ✓ | The data to serialize as JSON |
199
228
  | `indent` | `number` | | The number of spaces to use for indentation |
200
229
 
201
- **Returns:** `void`
230
+ **Returns:** `Promise<void>`
202
231
 
203
232
  ```ts
204
233
  await fs.writeJsonAsync('config.json', { version: '1.0.0', debug: false })
@@ -236,7 +265,7 @@ Asynchronously appends content to a file.
236
265
  | `path` | `string` | ✓ | The file path to append to |
237
266
  | `content` | `Buffer | string` | ✓ | The content to append |
238
267
 
239
- **Returns:** `void`
268
+ **Returns:** `Promise<void>`
240
269
 
241
270
  ```ts
242
271
  await fs.appendFileAsync('log.txt', 'New line\n')
@@ -256,7 +285,7 @@ Synchronously ensures a file exists with the specified content, creating directo
256
285
  | `content` | `string` | ✓ | The content to write to the file |
257
286
  | `overwrite` | `any` | | Whether to overwrite the file if it already exists |
258
287
 
259
- **Returns:** `void`
288
+ **Returns:** `string`
260
289
 
261
290
  ```ts
262
291
  fs.ensureFile('logs/app.log', '', false)
@@ -276,7 +305,7 @@ Asynchronously ensures a file exists with the specified content, creating direct
276
305
  | `content` | `string` | ✓ | The content to write to the file |
277
306
  | `overwrite` | `any` | | Whether to overwrite the file if it already exists |
278
307
 
279
- **Returns:** `void`
308
+ **Returns:** `Promise<string>`
280
309
 
281
310
  ```ts
282
311
  await fs.ensureFileAsync('config/settings.json', '{}', true)
@@ -294,7 +323,7 @@ Synchronously ensures a directory exists, creating parent directories as needed.
294
323
  |------|------|----------|-------------|
295
324
  | `path` | `string` | ✓ | The directory path to create |
296
325
 
297
- **Returns:** `void`
326
+ **Returns:** `string`
298
327
 
299
328
  ```ts
300
329
  fs.ensureFolder('logs/debug')
@@ -312,7 +341,7 @@ Asynchronously ensures a directory exists, creating parent directories as needed
312
341
  |------|------|----------|-------------|
313
342
  | `path` | `string` | ✓ | The directory path to create |
314
343
 
315
- **Returns:** `void`
344
+ **Returns:** `Promise<string>`
316
345
 
317
346
  ```ts
318
347
  await fs.ensureFolderAsync('logs/debug')
@@ -330,7 +359,7 @@ Alias for ensureFolder. Synchronously creates a directory and all parent directo
330
359
  |------|------|----------|-------------|
331
360
  | `folder` | `string` | ✓ | The directory path to create |
332
361
 
333
- **Returns:** `void`
362
+ **Returns:** `string`
334
363
 
335
364
  ```ts
336
365
  fs.mkdirp('deep/nested/path')
@@ -388,7 +417,7 @@ Asynchronously checks if a file or directory exists.
388
417
  |------|------|----------|-------------|
389
418
  | `path` | `string` | ✓ | The path to check for existence |
390
419
 
391
- **Returns:** `void`
420
+ **Returns:** `Promise<boolean>`
392
421
 
393
422
  ```ts
394
423
  if (await fs.existsAsync('config.json')) {
@@ -398,6 +427,34 @@ if (await fs.existsAsync('config.json')) {
398
427
 
399
428
 
400
429
 
430
+ ### isSymlink
431
+
432
+ Checks if a path is a symbolic link.
433
+
434
+ **Parameters:**
435
+
436
+ | Name | Type | Required | Description |
437
+ |------|------|----------|-------------|
438
+ | `path` | `string` | ✓ | The path to check |
439
+
440
+ **Returns:** `boolean`
441
+
442
+
443
+
444
+ ### realpath
445
+
446
+ Resolves a symlink to its real path. Returns the resolved path as-is if not a symlink.
447
+
448
+ **Parameters:**
449
+
450
+ | Name | Type | Required | Description |
451
+ |------|------|----------|-------------|
452
+ | `path` | `string` | ✓ | The path to resolve |
453
+
454
+ **Returns:** `string`
455
+
456
+
457
+
401
458
  ### stat
402
459
 
403
460
  Synchronously returns the stat object for a file or directory.
@@ -408,7 +465,7 @@ Synchronously returns the stat object for a file or directory.
408
465
  |------|------|----------|-------------|
409
466
  | `path` | `string` | ✓ | The path to stat |
410
467
 
411
- **Returns:** `void`
468
+ **Returns:** `Stats`
412
469
 
413
470
  ```ts
414
471
  const info = fs.stat('package.json')
@@ -427,7 +484,7 @@ Asynchronously returns the stat object for a file or directory.
427
484
  |------|------|----------|-------------|
428
485
  | `path` | `string` | ✓ | The path to stat |
429
486
 
430
- **Returns:** `void`
487
+ **Returns:** `Promise<Stats>`
431
488
 
432
489
  ```ts
433
490
  const info = await fs.statAsync('package.json')
@@ -544,7 +601,7 @@ Asynchronously removes a file.
544
601
  |------|------|----------|-------------|
545
602
  | `path` | `string` | ✓ | The path of the file to remove |
546
603
 
547
- **Returns:** `void`
604
+ **Returns:** `Promise<void>`
548
605
 
549
606
  ```ts
550
607
  await fs.rm('temp/cache.tmp')
@@ -580,7 +637,7 @@ Asynchronously removes a directory and all its contents.
580
637
  |------|------|----------|-------------|
581
638
  | `dirPath` | `string` | ✓ | The path of the directory to remove |
582
639
 
583
- **Returns:** `void`
640
+ **Returns:** `Promise<void>`
584
641
 
585
642
  ```ts
586
643
  await fs.rmdir('temp/cache')
@@ -633,7 +690,7 @@ Asynchronously copies a file or directory. Auto-detects whether the source is a
633
690
  |----------|------|-------------|
634
691
  | `overwrite` | `any` | Whether to overwrite existing files at the destination |
635
692
 
636
- **Returns:** `void`
693
+ **Returns:** `Promise<void>`
637
694
 
638
695
  ```ts
639
696
  await fs.copyAsync('src/config.json', 'backup/config.json')
@@ -673,7 +730,7 @@ Asynchronously moves (renames) a file or directory. Falls back to copy + delete
673
730
  | `src` | `string` | ✓ | The source path to move from |
674
731
  | `dest` | `string` | ✓ | The destination path to move to |
675
732
 
676
- **Returns:** `void`
733
+ **Returns:** `Promise<void>`
677
734
 
678
735
  ```ts
679
736
  await fs.moveAsync('temp/draft.txt', 'final/document.txt')
@@ -703,7 +760,7 @@ Recursively walks a directory and returns arrays of file and directory paths. By
703
760
  | `include` | `string | string[]` | ] - Glob patterns to include (only matching paths are returned) |
704
761
  | `relative` | `boolean` | When true, returned paths are relative to `baseDir` instead of absolute. |
705
762
 
706
- **Returns:** `void`
763
+ **Returns:** `{ directories: string[], files: string[] }`
707
764
 
708
765
  ```ts
709
766
  const result = fs.walk('src', { files: true, directories: false })
@@ -734,7 +791,7 @@ Asynchronously and recursively walks a directory and returns arrays of file and
734
791
  | `include` | `string | string[]` | ] - Glob patterns to include (only matching paths are returned) |
735
792
  | `relative` | `boolean` | When true, returned paths are relative to `baseDir` instead of absolute. |
736
793
 
737
- **Returns:** `void`
794
+ **Returns:** `Promise<{ directories: string[], files: string[] }>`
738
795
 
739
796
  ```ts
740
797
  const result = await fs.walkAsync('src', { exclude: ['node_modules'] })
@@ -34,7 +34,7 @@ Lists files in the Git repository using git ls-files command. This method provid
34
34
  | `exclude` | `string | string[]` | Patterns to exclude from results |
35
35
  | `baseDir` | `string` | Base directory to list files from |
36
36
 
37
- **Returns:** `void`
37
+ **Returns:** `Promise<string[]>`
38
38
 
39
39
  ```ts
40
40
  // Get all tracked files
@@ -62,7 +62,7 @@ Gets the latest commits from the repository. Returns an array of commit objects
62
62
  |------|------|----------|-------------|
63
63
  | `numberOfChanges` | `number` | | The number of recent commits to return |
64
64
 
65
- **Returns:** `void`
65
+ **Returns:** `Promise<Array<{ title: string, message: string, author: string }>>`
66
66
 
67
67
  ```ts
68
68
  const changes = await git.getLatestChanges(5)
@@ -83,7 +83,7 @@ Gets a lightweight commit log for one or more files. Returns the SHA and message
83
83
  |------|------|----------|-------------|
84
84
  | `files` | `string[]` | ✓ | File paths (absolute or relative to container.cwd) |
85
85
 
86
- **Returns:** `void`
86
+ **Returns:** `Array<{ sha: string, message: string }>`
87
87
 
88
88
  ```ts
89
89
  const log = git.fileLog('package.json')
@@ -107,7 +107,7 @@ Gets the diff for a file between two refs. By default compares from the current
107
107
  | `compareTo` | `string` | ✓ | The target ref (commit SHA, branch, tag) to compare to |
108
108
  | `compareFrom` | `string` | | The base ref to compare from (defaults to current HEAD) |
109
109
 
110
- **Returns:** `void`
110
+ **Returns:** `string`
111
111
 
112
112
  ```ts
113
113
  // Diff package.json between HEAD and a specific commit
@@ -144,6 +144,31 @@ git.displayDiff('src/index.ts', 'abc1234')
144
144
 
145
145
 
146
146
 
147
+ ### extractFolder
148
+
149
+ Extracts a folder (or entire repo) from a remote GitHub repository without cloning. Downloads the repo as a tarball and extracts only the specified subfolder, similar to how degit works. No .git history is included — just the files. Supports shorthand (`user/repo/path`), branch refs (`user/repo/path#branch`), and full GitHub URLs (`https://github.com/user/repo/tree/branch/path`).
150
+
151
+ **Parameters:**
152
+
153
+ | Name | Type | Required | Description |
154
+ |------|------|----------|-------------|
155
+ | `{ source, destination, branch }` | `{ source: string, destination: string, branch?: string }` | ✓ | Parameter { source, destination, branch } |
156
+
157
+ **Returns:** `Promise<{ files: string[], source: { user: string, repo: string, ref: string, subdir: string`
158
+
159
+ ```ts
160
+ // Extract a subfolder
161
+ await git.extractFolder({ source: 'soederpop/luca/src/assistants', destination: './my-assistants' })
162
+
163
+ // Specific branch
164
+ await git.extractFolder({ source: 'sveltejs/template', destination: './my-app', branch: 'main' })
165
+
166
+ // Full GitHub URL
167
+ await git.extractFolder({ source: 'https://github.com/user/repo/tree/main/examples', destination: './examples' })
168
+ ```
169
+
170
+
171
+
147
172
  ### getChangeHistoryForFiles
148
173
 
149
174
  Gets the commit history for a set of files or glob patterns. Accepts absolute paths, relative paths (resolved from container.cwd), or glob patterns. Returns commits that touched any of the matched files, with each entry noting which of your queried files were in that commit.
@@ -154,7 +179,7 @@ Gets the commit history for a set of files or glob patterns. Accepts absolute pa
154
179
  |------|------|----------|-------------|
155
180
  | `paths` | `string[]` | ✓ | File paths or glob patterns to get history for |
156
181
 
157
- **Returns:** `void`
182
+ **Returns:** `Array<{ sha: string, message: string, longMessage: string, filesMatched: string[] }>`
158
183
 
159
184
  ```ts
160
185
  const history = git.getChangeHistoryForFiles('src/container.ts', 'src/helper.ts')
@@ -168,11 +193,11 @@ const history = git.getChangeHistoryForFiles('src/node/features/*.ts')
168
193
  | Property | Type | Description |
169
194
  |----------|------|-------------|
170
195
  | `gitPath` | `string` | Resolve the git binary path via `which`, caching the result. |
171
- | `branch` | `any` | Gets the current Git branch name. |
172
- | `sha` | `any` | Gets the current Git commit SHA hash. |
173
- | `isRepo` | `any` | Checks if the current directory is within a Git repository. |
174
- | `isRepoRoot` | `any` | Checks if the current working directory is the root of the Git repository. |
175
- | `repoRoot` | `any` | Gets the absolute path to the Git repository root directory. This method caches the repository root path for performance. It searches upward from the current directory to find the .git directory. |
196
+ | `branch` | `string | null` | Gets the current Git branch name. |
197
+ | `sha` | `string | null` | Gets the current Git commit SHA hash. |
198
+ | `isRepo` | `boolean` | Checks if the current directory is within a Git repository. |
199
+ | `isRepoRoot` | `boolean` | Checks if the current working directory is the root of the Git repository. |
200
+ | `repoRoot` | `string | null` | Gets the absolute path to the Git repository root directory. This method caches the repository root path for performance. It searches upward from the current directory to find the .git directory. |
176
201
 
177
202
  ## State (Zod v4 schema)
178
203
 
@@ -265,6 +290,21 @@ git.displayDiff('src/index.ts', 'abc1234')
265
290
 
266
291
 
267
292
 
293
+ **extractFolder**
294
+
295
+ ```ts
296
+ // Extract a subfolder
297
+ await git.extractFolder({ source: 'soederpop/luca/src/assistants', destination: './my-assistants' })
298
+
299
+ // Specific branch
300
+ await git.extractFolder({ source: 'sveltejs/template', destination: './my-app', branch: 'main' })
301
+
302
+ // Full GitHub URL
303
+ await git.extractFolder({ source: 'https://github.com/user/repo/tree/main/examples', destination: './examples' })
304
+ ```
305
+
306
+
307
+
268
308
  **getChangeHistoryForFiles**
269
309
 
270
310
  ```ts
@@ -6,6 +6,8 @@ Google Calendar feature for listing calendars and reading events. Depends on the
6
6
 
7
7
  ```ts
8
8
  container.feature('googleCalendar', {
9
+ // An authorized instance of the googleAuth feature
10
+ auth,
9
11
  // Default calendar ID (default: "primary")
10
12
  defaultCalendarId,
11
13
  // Default timezone for event queries (e.g. "America/Chicago")
@@ -17,6 +19,7 @@ container.feature('googleCalendar', {
17
19
 
18
20
  | Property | Type | Description |
19
21
  |----------|------|-------------|
22
+ | `auth` | `any` | An authorized instance of the googleAuth feature |
20
23
  | `defaultCalendarId` | `string` | Default calendar ID (default: "primary") |
21
24
  | `timeZone` | `string` | Default timezone for event queries (e.g. "America/Chicago") |
22
25
 
@@ -5,9 +5,18 @@ Google Docs feature for reading documents and converting them to Markdown. Depen
5
5
  ## Usage
6
6
 
7
7
  ```ts
8
- container.feature('googleDocs')
8
+ container.feature('googleDocs', {
9
+ // An authorized instance of the googleAuth feature
10
+ auth,
11
+ })
9
12
  ```
10
13
 
14
+ ## Options (Zod v4 schema)
15
+
16
+ | Property | Type | Description |
17
+ |----------|------|-------------|
18
+ | `auth` | `any` | An authorized instance of the googleAuth feature |
19
+
11
20
  ## Methods
12
21
 
13
22
  ### getDocument
@@ -6,6 +6,8 @@ Google Drive feature for listing, searching, browsing, and downloading files. De
6
6
 
7
7
  ```ts
8
8
  container.feature('googleDrive', {
9
+ // An authorized instance of the googleAuth feature
10
+ auth,
9
11
  // Default corpus for file queries (default: user)
10
12
  defaultCorpora,
11
13
  // Default number of results per page (default: 100)
@@ -17,6 +19,7 @@ container.feature('googleDrive', {
17
19
 
18
20
  | Property | Type | Description |
19
21
  |----------|------|-------------|
22
+ | `auth` | `any` | An authorized instance of the googleAuth feature |
20
23
  | `defaultCorpora` | `string` | Default corpus for file queries (default: user) |
21
24
  | `pageSize` | `number` | Default number of results per page (default: 100) |
22
25
 
@@ -0,0 +1,214 @@
1
+ # GoogleMail (features.googleMail)
2
+
3
+ Google Mail feature for searching, reading, and watching Gmail messages. Depends on the googleAuth feature for authentication. Creates a Gmail v1 API client lazily. Supports Gmail search query syntax, individual message reading, and polling-based new mail detection with event emission.
4
+
5
+ ## Usage
6
+
7
+ ```ts
8
+ container.feature('googleMail', {
9
+ // An authorized instance of the googleAuth feature
10
+ auth,
11
+ // Gmail user ID (default: "me")
12
+ userId,
13
+ // Polling interval in ms for watching new mail (default: 30000)
14
+ pollInterval,
15
+ // Default message format when fetching (default: "full")
16
+ format,
17
+ })
18
+ ```
19
+
20
+ ## Options (Zod v4 schema)
21
+
22
+ | Property | Type | Description |
23
+ |----------|------|-------------|
24
+ | `auth` | `any` | An authorized instance of the googleAuth feature |
25
+ | `userId` | `string` | Gmail user ID (default: "me") |
26
+ | `pollInterval` | `number` | Polling interval in ms for watching new mail (default: 30000) |
27
+ | `format` | `string` | Default message format when fetching (default: "full") |
28
+
29
+ ## Methods
30
+
31
+ ### search
32
+
33
+ Search for messages using Gmail query syntax and/or structured filters.
34
+
35
+ **Parameters:**
36
+
37
+ | Name | Type | Required | Description |
38
+ |------|------|----------|-------------|
39
+ | `options` | `SearchMailOptions` | | Search filters including query, from, to, subject, date ranges |
40
+
41
+ `SearchMailOptions` properties:
42
+
43
+ | Property | Type | Description |
44
+ |----------|------|-------------|
45
+ | `query` | `string` | |
46
+ | `from` | `string` | |
47
+ | `to` | `string` | |
48
+ | `subject` | `string` | |
49
+ | `after` | `string` | |
50
+ | `before` | `string` | |
51
+ | `hasAttachment` | `boolean` | |
52
+ | `label` | `string` | |
53
+ | `isUnread` | `boolean` | |
54
+ | `maxResults` | `number` | |
55
+ | `pageToken` | `string` | |
56
+
57
+ **Returns:** `Promise<MailMessageList>`
58
+
59
+
60
+
61
+ ### getMessage
62
+
63
+ Get a single message by ID.
64
+
65
+ **Parameters:**
66
+
67
+ | Name | Type | Required | Description |
68
+ |------|------|----------|-------------|
69
+ | `messageId` | `string` | ✓ | The message ID |
70
+ | `format` | `'full' | 'metadata' | 'minimal' | 'raw'` | | Message format (defaults to options.format or 'full') |
71
+
72
+ **Returns:** `Promise<MailMessage>`
73
+
74
+
75
+
76
+ ### getThread
77
+
78
+ Get a full thread with all its messages.
79
+
80
+ **Parameters:**
81
+
82
+ | Name | Type | Required | Description |
83
+ |------|------|----------|-------------|
84
+ | `threadId` | `string` | ✓ | The thread ID |
85
+
86
+ **Returns:** `Promise<MailThread>`
87
+
88
+
89
+
90
+ ### listLabels
91
+
92
+ List all labels for the authenticated user.
93
+
94
+ **Returns:** `Promise<MailLabel[]>`
95
+
96
+
97
+
98
+ ### startWatching
99
+
100
+ Start watching for new mail by polling at a regular interval. Emits 'newMail' events with an array of new messages when they arrive. Uses Gmail history API to efficiently detect only new messages since the last check.
101
+
102
+ **Returns:** `Promise<void>`
103
+
104
+
105
+
106
+ ### stopWatching
107
+
108
+ Stop watching for new mail.
109
+
110
+ **Returns:** `void`
111
+
112
+
113
+
114
+ ## Getters
115
+
116
+ | Property | Type | Description |
117
+ |----------|------|-------------|
118
+ | `auth` | `GoogleAuth` | Access the google-auth feature lazily. |
119
+ | `userId` | `string` | Default user ID from options or 'me'. |
120
+ | `defaultFormat` | `'full' | 'metadata' | 'minimal' | 'raw'` | Default message format from options or 'full'. |
121
+ | `pollInterval` | `number` | Polling interval from options or 30 seconds. |
122
+
123
+ ## Events (Zod v4 schema)
124
+
125
+ ### messagesFetched
126
+
127
+ Messages were fetched from Gmail
128
+
129
+ **Event Arguments:**
130
+
131
+ | Name | Type | Description |
132
+ |------|------|-------------|
133
+ | `arg0` | `number` | Number of messages returned |
134
+
135
+
136
+
137
+ ### error
138
+
139
+ Gmail API error occurred
140
+
141
+ **Event Arguments:**
142
+
143
+ | Name | Type | Description |
144
+ |------|------|-------------|
145
+ | `arg0` | `any` | The error |
146
+
147
+
148
+
149
+ ### watchStarted
150
+
151
+ Mail watching has started
152
+
153
+
154
+
155
+ ### watchStopped
156
+
157
+ Mail watching has stopped
158
+
159
+
160
+
161
+ ### newMail
162
+
163
+ New mail arrived (emitted by watch)
164
+
165
+ **Event Arguments:**
166
+
167
+ | Name | Type | Description |
168
+ |------|------|-------------|
169
+ | `arg0` | `array` | Array of new MailMessage objects |
170
+
171
+
172
+
173
+ ## State (Zod v4 schema)
174
+
175
+ | Property | Type | Description |
176
+ |----------|------|-------------|
177
+ | `enabled` | `boolean` | Whether this feature is currently enabled |
178
+ | `lastQuery` | `string` | Last search query used |
179
+ | `lastResultCount` | `number` | Number of messages returned in last search |
180
+ | `lastError` | `string` | Last Gmail API error message |
181
+ | `watchExpiration` | `string` | ISO timestamp when the current watch expires |
182
+
183
+ ## Examples
184
+
185
+ **features.googleMail**
186
+
187
+ ```ts
188
+ const mail = container.feature('googleMail')
189
+
190
+ // Search by sender
191
+ const fromBoss = await mail.search({ from: 'boss@company.com' })
192
+
193
+ // Use Gmail query string
194
+ const unread = await mail.search({ query: 'is:unread category:primary' })
195
+
196
+ // Read a specific message
197
+ const msg = await mail.getMessage('message-id-here')
198
+
199
+ // Get a full thread
200
+ const thread = await mail.getThread('thread-id-here')
201
+
202
+ // List labels
203
+ const labels = await mail.listLabels()
204
+
205
+ // Watch for new mail (polls and emits 'newMail' events)
206
+ mail.on('newMail', (messages) => {
207
+ console.log(`Got ${messages.length} new messages!`)
208
+ })
209
+ await mail.startWatching()
210
+
211
+ // Stop watching
212
+ mail.stopWatching()
213
+ ```
214
+
@@ -6,6 +6,8 @@ Google Sheets feature for reading spreadsheet data as JSON, CSV, or raw arrays.
6
6
 
7
7
  ```ts
8
8
  container.feature('googleSheets', {
9
+ // An authorized instance of the googleAuth feature
10
+ auth,
9
11
  // Default spreadsheet ID for operations
10
12
  defaultSpreadsheetId,
11
13
  })
@@ -15,6 +17,7 @@ container.feature('googleSheets', {
15
17
 
16
18
  | Property | Type | Description |
17
19
  |----------|------|-------------|
20
+ | `auth` | `any` | An authorized instance of the googleAuth feature |
18
21
  | `defaultSpreadsheetId` | `string` | Default spreadsheet ID for operations |
19
22
 
20
23
  ## Methods